UNIX域套接字

一、前言

作用:

用于实现一台主机上的两个进程的通信

二、用UDP服务端/客户端模型来实现一台主机上的两个进程的通信

2.1、服务器端

udp_server.c

cs 复制代码
#include<stdio.h>               // 包含标准输入输出库,用于printf等函数  
#include <sys/types.h>          // 包含系统数据类型定义,如pid_t, socklen_t等  
#include <sys/socket.h>         // 包含套接字编程相关函数和数据结构  
// 注意:这里应该使用<sys/un.h>而不是<linux/un.h>,因为<linux/un.h>是Linux特有的,可能不是所有UNIX系统都支持  
#include <sys/un.h>             // 包含Unix域套接字相关数据结构  
#include <string.h>             // 包含字符串操作函数,如strcpy, memset等  
  
#define BUF_SIZE 20             // 定义缓冲区大小为20字节  
  
int main()  
{  
    // 1. 创建socket  
    int iServer = socket(PF_UNIX, SOCK_DGRAM, 0); // 创建一个Unix域数据报套接字  
    if (-1 == iServer)  
    {  
        printf("create socket error!----------\r\n"); // 如果创建失败,打印错误信息  
        return -1;                                  // 返回-1表示程序异常退出  
    }  
    printf("1:socket ok!--------------\r\n");       // 打印socket创建成功的信息  
  
    // 2. 绑定socket到指定路径  
    struct sockaddr_un stServer; // 定义一个Unix域套接字地址结构  
    memset(&stServer, 0, sizeof(struct sockaddr_un)); // 初始化地址结构,将其所有字节设置为0  
    stServer.sun_family = PF_UNIX;                    // 设置地址家族为Unix域  
    strcpy(stServer.sun_path, "Afanda");              // 设置套接字文件路径为"Afanda"  
    unlink(stServer.sun_path);                        // 如果该路径已存在,则删除它(避免绑定失败)  
    int ret = bind(iServer, (struct sockaddr *)&stServer, sizeof(struct sockaddr_un)); // 绑定socket到指定路径  
    if (-1 == ret)  
    {  
        printf("bind error!------------\r\n");        // 如果绑定失败,打印错误信息  
        return -1;                                   // 返回-1表示程序异常退出  
    }  
    printf("2:bind ok!-------------\r\n");           // 打印绑定成功的信息  
  
    // 3. 使用recvfrom接收数据,并使用sendto发送数据  
    char buf[BUF_SIZE] = {0};                        // 定义一个缓冲区用于接收和发送数据  
    struct sockaddr_un stClient;                     // 定义一个结构用于存储客户端的地址信息  
    socklen_t len = sizeof(struct sockaddr_un);      // 设置地址结构的大小  
  
    while (1) // 无限循环,等待接收数据  
    {  
        if (recvfrom(iServer, buf, BUF_SIZE, 0, (struct sockaddr *)&stClient, &len) > 0) // 接收数据  
        {  
            printf("recv data:%s\r\n", buf);         // 打印接收到的数据  
            // 注意:这里发送的数据长度应该是实际接收到的数据长度,而不是BUF_SIZE  
            ret = sendto(iServer, buf, strlen(buf), 0, (struct sockaddr *)&stClient, len); // 发送数据回客户端  
            printf("sendto ok,ret=%d\r\n", ret);     // 打印发送结果  
        }  
    }  
    // 注意:由于上面是一个无限循环,所以这里的return 0;实际上永远不会被执行到  
    return 0;  
}

2.2、客户端

udp_client.c

cs 复制代码
#include<stdio.h>               // 引入标准输入输出库,用于printf等函数  
#include <sys/types.h>          // 引入系统数据类型定义,如pid_t, socklen_t等  
#include <sys/socket.h>         // 引入套接字编程相关函数和数据结构  
#include <linux/un.h>           // 引入Linux特有的Unix域套接字相关数据结构  
                                // 注意:通常在非Linux系统上,应该使用<sys/un.h>代替  
#include <string.h>             // 引入字符串操作函数,如strcpy, memset等  
  
#define BUF_SIZE 20             // 定义缓冲区大小为20字节  
  
int main()  
{  
    // 1. 创建socket  
    // 创建一个Unix域数据报套接字  
    int iClient = socket(PF_UNIX, SOCK_DGRAM, 0);  
    if (-1 == iClient)  
    {  
        printf("socket error!------------\r\n"); // 如果socket创建失败,打印错误信息  
        return -1;                              // 返回-1表示程序异常退出  
    }  
    printf("1:socket ok!-----------\r\n");       // 打印socket创建成功的信息  
  
    // 注意:在客户端程序中,通常不需要bind操作,因为它只是连接到服务器  
    // 但为了演示,这里仍然进行了bind操作,但通常这样做是不必要的  
  
    // 2. 尝试在客户端上进行bind操作(通常这是不必要的)  
    struct sockaddr_un stServer; // 用于服务器地址的结构体  
    memset(&stServer, 0, sizeof(struct sockaddr_un)); // 初始化结构体,将所有字节设置为0  
    stServer.sun_family = PF_UNIX; // 设置地址家族为Unix域  
    strcpy(stServer.sun_path, "Afanda"); // 设置服务器套接字文件路径为"Afanda"  
  
    // 这里的stClient结构体和bind操作实际上是多余的,因为客户端不需要绑定到特定的路径  
    // 但为了与您的代码保持一致,我仍然会进行注释  
    struct sockaddr_un stClient; // 用于客户端地址的结构体(通常不需要)  
    memset(&stClient, 0, sizeof(struct sockaddr_un)); // 初始化结构体,将所有字节设置为0  
    stClient.sun_family = PF_UNIX; // 设置地址家族为Unix域  
    strcpy(stClient.sun_path, "hanghaiwang"); // 设置客户端套接字文件路径为"hanghaiwang"  
    unlink(stClient.sun_path); // 如果该文件已存在,则删除它(避免bind失败)  
  
    // 尝试将客户端socket绑定到"hanghaiwang"路径(这通常是不必要的)  
    int ret = bind(iClient, (struct sockaddr *)&stClient, sizeof(struct sockaddr_un));  
    if (-1 == ret)  
    {  
        printf("bind error!-------------\r\n"); // 如果bind失败,打印错误信息  
        return -1;                             // 返回-1表示程序异常退出  
    }  
  
    char buf[BUF_SIZE] = {0}; // 定义一个缓冲区,用于存储输入和接收到的数据  
    socklen_t len = sizeof(struct sockaddr_un); // 设置地址结构的大小  
  
    // 3. 无限循环,用于接收用户输入并发送到服务器,然后接收服务器的响应  
    while (1)  
    {  
        memset(buf, 0, BUF_SIZE); // 清空缓冲区,准备接收新的输入  
        fgets(buf, BUF_SIZE, stdin); // 从标准输入(通常是键盘)读取数据到缓冲区  
  
        // 发送到服务器  
        if (sendto(iClient, buf, strlen(buf), 0, (struct sockaddr *)&stServer, len) > 0)  
        {  
            // 注意:发送的数据长度应该是实际输入的数据长度(包括换行符),而不是BUF_SIZE  
            memset(buf, 0, BUF_SIZE); // 清空缓冲区,准备接收服务器的响应  
            ret = recvfrom(iClient, buf, BUF_SIZE, 0, (struct sockaddr *)&stServer, &len);  
            // 接收服务器的响应  
            printf("recv ok,ret=%d,data:%s\r\n", ret, buf); // 打印接收到的响应和字节数  
        }  
    }  
  
    // 注意:由于while(1)是一个无限循环,所以这里的return 0;实际上永远不会被执行到  
    // 但从代码结构完整性考虑,我们仍然保留它  
    return 0;  
}
相关推荐
取酒鱼食--【余九】5 分钟前
深度学习经典网络解析:ResNet
网络·人工智能·深度学习·神经网络·resnet·卷积神经网络·残差神经网络
风清再凯13 分钟前
05-k8s网络
网络·容器·kubernetes
今麦郎xdu_16 分钟前
【Linux系统】命令行参数和环境变量
linux·服务器·c语言·c++
还不秃顶的计科生19 分钟前
linux下conda未安装的解决方法(离线安装linux下的conda)
linux·运维·服务器
DeeplyMind34 分钟前
Linux的Dynamic debug功能
linux·dynamic debug
LJ-SEU44 分钟前
win-ubuntu网络转发
linux·网络·ubuntu
QT 小鲜肉1 小时前
【个人成长笔记】在Ubuntu中的Linux系统安装 anaconda 及其相关终端命令行
linux·笔记·深度学习·学习·ubuntu·学习方法
QT 小鲜肉1 小时前
【个人成长笔记】在Ubuntu中的Linux系统安装实验室WIFI驱动安装(Driver for Linux RTL8188GU)
linux·笔记·学习·ubuntu·学习方法
爱学习饼1 小时前
CentOS下安装配置JDK24和tomcat11
linux·运维·centos
关关长语2 小时前
(一) Dotnet使用MCP的Csharp SDK
网络·.net·mcp