UNIX域套接字

一、前言

作用:

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

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

2.1、服务器端

udp_server.c

#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

#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;  
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值