c - UNIX Domain Socket 编程 3 个套接字

标签 c sockets unix-socket

我正在尝试创建一个支持 3 个套接字的 server.c 文件,这些套接字由 3 个各自的客户端类表示:client1、client2、client3。

在我的 server.c 文件中,我目前有在互联网上找到的这段代码。

如果我想让它有 3 个 socket 。我想使用 select() 命令来查看 3 个客户端的写入事件。我的问题是如何使用它来支持 3 个套接字。

我可以将 3 个客户端绑定(bind)到服务器可以监听的 3 个套接字吗?如果是这样,服务器如何分别监听这3个套接字?可能用数组吗?

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

#define socket1 "sock1"
#define socket2 "sock2"
#define socket3 "sock3"

int main(int argc, char *argv[]) {
    //struct sockaddr_un addr;
    struct sockaddr_un addr1;
    struct sockaddr_un addr2;
    struct sockaddr_un addr3;
    char buf[100];
    int socket1;
    int socket2;
    int socket3;
    //int fd;
    int cl,rc;

    if (argc > 1) socket_path=argv[1];

    if ( (socket1 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        perror("socket error");
        exit(-1);
    }

    memset(&addr1, 0, sizeof(addr1));
    addr1.sun_family = AF_UNIX;
    strncpy(addr1.sun_path, socket_path, sizeof(addr1.sun_path)-1);

    unlink(socket_path1);

    if ( (socket2 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        perror("socket error");
        exit(-1);
    }

    memset(&addr2, 0, sizeof(addr2));
    addr1.sun_family = AF_UNIX;
    strncpy(addr2.sun_path, socket_path, sizeof(addr2.sun_path)-1);

    unlink(socket_path2);

    if ( (socket3 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        perror("socket error");
        exit(-1);
    }

    memset(&addr3, 0, sizeof(addr3));
    addr3.sun_family = AF_UNIX;
    strncpy(addr3.sun_path, socket_path, sizeof(addr3.sun_path)-1);

    unlink(socket_path3);

    if (bind(socket1, (struct sockaddr*)&addr1, sizeof(addr1)) == -1) {
        perror("bind error");
        exit(-1);
    }

    if (bind(socket2, (struct sockaddr*)&addr2, sizeof(addr2)) == -1) {
        perror("bind error");
        exit(-1);
    }

    if (bind(socket3, (struct sockaddr*)&addr3, sizeof(addr3)) == -1) {
        perror("bind error");
        exit(-1);
    }

    if (listen(socket1, 5) == -1) {
        perror("listen error");
        exit(-1);
    }

    if (listen(socket2, 5) == -1) {
        perror("listen error");
        exit(-1);
    }

    if (listen(socket3, 5) == -1) {
        perror("listen error");
        exit(-1);
    }

    while (1) {
        if ( (cl = accept(fd, NULL, NULL)) == -1) {
            perror("accept error");
            continue;
        }

        while ( (rc=read(cl,buf,sizeof(buf))) > 0) {
            printf("read %u bytes: %.*s\n", rc, rc, buf);
        }
        if (rc == -1) {
            perror("read");
            exit(-1);
        }
        else if (rc == 0) {
            printf("EOF\n");
            close(cl);
        }
    }

    return 0;
}

最佳答案

如果你想在同一个进程中使用三个监听套接字,你必须让它们是唯一的。在 AF_INET家人,你这样做 bind(2) -ing 不同的端口,在 AF_UNIX家人,你用不同的方式做到这一点。

还有你的线路:

char *socket_path = "\0hidden";

至少有两个问题:

  • 赋值右侧的字符串文字类型为 const char[8],它会衰减为 const char* 指针类型,但不是 char* 类型。使左侧const char*。另外,使用更高的警告级别进行编译,例如 -Wall -pedantic,以获得编译器的帮助。
  • 字符串开头的零字节使 strncpy(3) 不复制任何内容,因为它从 src 指向的字符串中复制最多 n 个字符,包括终止空字节 ('\0').

创建一个函数,以 UNIX 路径作为参数,创建、绑定(bind)套接字并将其标记为监听,并返回创建的套接字描述符。调用它三次 - 您有三个正在监听的 UNIX 套接字。设置select(2)在它们上阅读 - 这会告诉您客户端连接何时到达。届时请调用accept(2)在事件套接字上获取已连接的客户端套接字,该套接字与监听套接字本身是分开的。

关于c - UNIX Domain Socket 编程 3 个套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30143335/

相关文章:

c - 为什么我在 C 中使用 UDP 套接字接收文件时会出现一些垃圾字节?

java - jvisualvm:软件导致连接中止:套接字写入错误

mysql - Unix 域套接字错误代码?

c - 需要帮助调试简单的控制台游戏

c - 写入系统调用参数寄存器

c - 为什么服务器在关闭客户端连接时进入无限循环

c - 在 Solaris Sparc 64 位上,64 位进程可以加载 32 位共享库吗

linux - 是否可以找到哪个用户位于本地主机 TCP 连接的另一端?

c - 尽管轮询文件描述符,但不可靠的 http 客户端

sockets - 如何使用 unix 套接字从容器内部与 docker 守护进程进行通信?