Unix域套接字 2024.9.5

1.流式域套接字服务器端实现

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>

int main() {
    int oldfd;

    // 创建 socket
    if ((oldfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        return -1;
    }

    // 判断文件是否存在,存在就删除
    if (access("./myclient", F_OK) == 0) {
        if (unlink("./myclient") == -1) {
            perror("unlink");
            return -1;
        }
    }

    // 设置客户端套接字地址
    struct sockaddr_un client;
    client.sun_family = AF_UNIX;
    strcpy(client.sun_path, "./myclient");

    // 绑定客户端套接字(可选)
    if (bind(oldfd, (struct sockaddr *)&client, sizeof(client)) == -1) {
        perror("bind");
        return -1;
    }

    // 设置服务器套接字地址
    struct sockaddr_un server;
    server.sun_family = AF_UNIX;
    strcpy(server.sun_path, "./myserver");

    // 连接服务器
    if (connect(oldfd, (struct sockaddr *)&server, sizeof(server)) == -1) {
        perror("connect");
        return -1;
    }

    printf("连接服务器成功\n");

    char buff[1024];

    while (1) {
        // 清空缓冲区
        bzero(buff, sizeof(buff));

        // 获取用户输入
        printf("请输入要发送的信息: ");
        fgets(buff, sizeof(buff), stdin);
        
        // 去掉换行符
        buff[strlen(buff) - 1] = '\0';

        // 发送信息
        if (send(oldfd, buff, strlen(buff), 0) == -1) {
            perror("send");
            return -1;
        }
        printf("发送成功\n");

        // 如果输入 quit,退出循环
        if (strcmp(buff, "quit") == 0)
            break;

        // 接收服务器信息
        if (recv(oldfd, buff, sizeof(buff), 0) == -1) {
            perror("recv");
            return -1;
        }
        
        printf("接收服务器的信息: %s\n", buff);
    }

    // 关闭 socket
    close(oldfd);
    return 0;
}

2、报式域套接字服务器端

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>

int main() {
    int oldfd;

    // 创建 socket
    if ((oldfd = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) {  // 使用 SOCK_DGRAM,因为它更适合 recvfrom/sendto 的无连接方式
        perror("socket");
        return -1;
    }

    // 判断文件是否存在,存在就删除
    if (access("./myserver", F_OK) == 0) {
        if (unlink("./myserver") == -1) {
            perror("unlink");
            return -1;
        }
    }

    // 设置服务器套接字地址
    struct sockaddr_un server;
    server.sun_family = AF_UNIX;
    strcpy(server.sun_path, "./myserver");

    // 绑定服务器地址
    if (bind(oldfd, (struct sockaddr *)&server, sizeof(server)) == -1) {
        perror("bind");
        return -1;
    }

    // 进入消息收发循环
    struct sockaddr_un client;  // 定义客户端信息结构体
    socklen_t clientlen = sizeof(client);
    char buff[1024];

    while (1) {
        // 清空缓冲区
        bzero(buff, sizeof(buff));

        // 接收客户端消息
        if (recvfrom(oldfd, buff, sizeof(buff), 0, (struct sockaddr *)&client, &clientlen) == -1) {
            perror("recvfrom");
            return -1;
        }
        
        printf("接收到 %s 的消息\n", client.sun_path);
        printf("收到客户端信息: %s\n", buff);

        // 添加标识符后再发送回客户端
        strcat(buff, "*_*");

        // 发送消息回客户端
        if (sendto(oldfd, buff, strlen(buff), 0, (struct sockaddr *)&client, clientlen) == -1) {
            perror("sendto");
            return -1;
        }

        printf("转发成功\n");
    }

    // 关闭文件描述符
    close(oldfd);
    return 0;
}

客户端

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>

int main() {
    // 1、创建报式域套接字
    int oldfd = socket(AF_UNIX, SOCK_DGRAM, 0);
    if (oldfd == -1) {
        perror("socket");
        return -1;
    }

    // 2、判断文件是否存在,存在就删除
    if (access("./myclient", F_OK) == 0) {
        if (unlink("./myclient") == -1) {
            perror("unlink");
            return -1;
        }
    }

    // 3、绑定客户端套接字
    struct sockaddr_un client;  // 定义客户端信息结构体
    client.sun_family = AF_UNIX;
    strcpy(client.sun_path, "./myclient");
    
    if (bind(oldfd, (struct sockaddr *)&client, sizeof(client)) == -1) {
        perror("bind");
        return -1;
    }

    // 4、收发消息
    struct sockaddr_un server;  // 定义服务器端信息结构体
    server.sun_family = AF_UNIX;
    strcpy(server.sun_path, "./myserver");  // 注意这里填充服务器端的文件

    char buff[1024];
    
    while (1) {
        // 获取用户输入
        printf("请输入要发送的信息: ");
        fgets(buff, sizeof(buff), stdin);

        // 去掉换行符
        buff[strlen(buff) - 1] = '\0';

        // 发送消息到服务器
        int len = sendto(oldfd, buff, strlen(buff), 0, (struct sockaddr *)&server, sizeof(server));
        if (len == -1) {
            perror("sendto");
            break;
        }

        // 接收服务器回复的消息
        if (recvfrom(oldfd, buff, sizeof(buff), 0, NULL, NULL) == -1) {
            perror("recvfrom");
            break;
        }

        printf("服务器发来信息: %s\n", buff);

        // 如果发送的信息是 "quit",则退出循环
        if (strcmp(buff, "quit") == 0) {
            break;
        }
    }

    // 关闭套接字
    close(oldfd);
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值