C/Unix中的Socketpair()

NAS*_*ern 29 c unix sockets ipc

我在同一系统上有2个应用程序,我需要来回通信.根据我的研究,我认为这称为Inter Process Communication,使用socketpair()是解决我问题的最佳方法.

我正在撕裂我的头发(字面意思)试图开始在C中创建带socketpair()的套接字.根据我的理解,套接字是一个非常复杂的主题,我是一个新手C程序员肯定无法帮助这种情况.

我用谷歌搜索过去48小时,阅读教程等,但我仍然无法得到它.我理解这个概念,但代码太混乱了.我已经读了几遍这篇文章:http://beej.us/guide/bgnet/html/single/bgnet.html,但这还不够简单.

有人可以提供一些例子(如此简单的五年级学生可以理解)或指向我一个很好的教程?

Use*_*ess 57

socketpair只能在创建两个进程的位置使用,如下所示:

  1. 调用socketpair- 现在你有两个套接字文件描述符(单个管道的两端)
    • 提名一端为父母,一端为子女.无所谓,只需做出选择并在以后坚持下去
  2. 呼叫fork- 现在你有两个进程
    1. 如果fork返回零,你就是孩子.关闭文件描述符,保留描述符,并将其用作此进程的管道末尾
    2. 如果fork返回非零,则您是父级.关闭文件描述符,保留文件描述符并将其用作管道的末尾
  3. 你现在有两个进程,每个进程有一个文件描述符代表同一个管道的不同端.请注意,两个进程都运行相同的程序,但在调用后它们跟随不同的分支fork.如果调用write其套接字,则将能够从其套接字读取该数据,反之亦然

这是代码的直接翻译:

void child(int socket) {
    const char hello[] = "hello parent, I am child";
    write(socket, hello, sizeof(hello)); /* NB. this includes nul */
    /* go forth and do childish things with this end of the pipe */
}

void parent(int socket) {
    /* do parental things with this end, like reading the child's message */
    char buf[1024];
    int n = read(socket, buf, sizeof(buf));
    printf("parent received '%.*s'\n", n, buf);
}

void socketfork() {
    int fd[2];
    static const int parentsocket = 0;
    static const int childsocket = 1;
    pid_t pid;

    /* 1. call socketpair ... */
    socketpair(PF_LOCAL, SOCK_STREAM, 0, fd);

    /* 2. call fork ... */
    pid = fork();
    if (pid == 0) { /* 2.1 if fork returned zero, you are the child */
        close(fd[parentsocket]); /* Close the parent file descriptor */
        child(fd[childsocket]);
    } else { /* 2.2 ... you are the parent */
        close(fd[childsocket]); /* Close the child file descriptor */
        parent(fd[parentsocket]);
    }
    exit(0); /* do everything in the parent and child functions */
}
Run Code Online (Sandbox Code Playgroud)

请注意,这只是示例代码:我遗漏了所有错误检查和合理的流协议.


如果您想要两个独立的程序进行通信(例如,您有一个名为client的可执行文件,一个名为server的可执行文件),则无法使用此机制.相反,你可能会:

  • 使用UNIX套接字(其中一个主机上的IPC管道由文件名标识 - 这仅在客户端服务器在同一台机器上运行时才有效)
  • 或使用TCP/IP套接字(其中IP地址和端口标识管道,客户端服务器可以在不同的计算机上)

如果您不特别需要套接字,并且您很高兴要求客户端服务器在同一台计算机上运行,​​您还可以使用共享内存或消息队列.

  • 实际上,您可以将描述符传递给不相关的进程:请参阅sendmsg/recvmsg和"描述符传递".这似乎是一个受欢迎的搜索:) (2认同)

R..*_*R.. 7

socketpair创建一对匿名套接字,通常是unix/local套接字,它们只对父进程和子进程之间的通信有用,或者在需要使用它们的进程可以从公共祖先继承文件描述符的其他情况下有用.

如果你打算做无关之间的通信(在亲子的感觉)的过程,你需要使用socket,bind以及connect在一个进程中创建一个监听套接字,并创建一个客户端套接字连接到它的其它过程.