C / Unix中的Socketpair()

时间:2012-07-12 21:39:24

标签: c sockets unix ipc

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

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

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

有人可以提供一些例子(五年级学生可以理解这么简单)或者指点一个好的教程吗?

4 个答案:

答案 0 :(得分:55)

您只能在创建两个流程的地方使用socketpair,如下所示:

  1. call socketpair - 现在你有两个套接字文件描述符(单个管道的两端)
    • 指定一端为父级,另一端为结尾。无论是哪个,只是做出选择并在以后坚持下去
  2. 致电fork - 现在您有两个流程
    1. 如果fork返回零,那么您就是孩子。关闭文件描述符,保留描述符,并将其用作此进程的管道末尾
    2. 如果fork返回非零,则您是父级。关闭文件描述符,保留一个并将其用作管道的末尾
  3. 您现在有两个进程,每个进程都有一个文件描述符,表示同一个管道的不同端。请注意,两个进程都运行相同的程序,但在调用fork后它们跟随不同的分支。如果 parent 在其套接字上调用write child 将能够从套接字中读取该数据,反之亦然< / LI>

    以下是代码的直接翻译:

    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 */
    }
    

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


    如果您想要两个单独的程序进行通信(例如,您有一个名为 client 的可执行文件,一个名为 server 的程序),您可以不要使用这种机制。相反,你可能会:

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

    如果您没有专门需要套接字,并且您很高兴要求在同一台计算机上运行客户端服务器,您也可以使用共享内存或消息队列。

答案 1 :(得分:6)

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

如果您要在不相关(在父母意义上)进程之间进行通信,则需要使用socketbindconnect来创建侦听套接字一个进程并创建一个客户端套接字以在另一个进程中连接它。

答案 2 :(得分:1)

对于两个进程之间的通信,是的,Inter Process Communication或IPC是您应该寻找的。 套接字只是通信方法之一,如果必须实现一对多连接,则非常有用。意味着,一个服务器进程以请求 - 响应方式与许多客户端进程通信。由于您是IPC的新手,因此可以理解套接字地址和所涉及的详细信息可能难以理解。 (虽然你会在适当的时候找到它们很简单: - ))

对于您的问题,我建议您使用更简单的IPC机制,如Pipe,FIFO,Message Queue。 我不确定你是如何得出使用socketpair的结论的。由于您没有提及您需要的IPC设计或类型,并且基于使用级别,我强烈建议您查看某些书籍或互联网中的管道或FIFO样本代码。它们看起来应该比套接字更容易实现和工作。

答案 3 :(得分:-2)

使用TCP / IP。虽然还有其他可用的IPC机制(例如Unix域套接字和SYSV IPC),但出于多种原因,最好使用TCP / IP。以下是一些:

  1. 网上有很多教程和其他信息,描述了如何进行TCP / IP
  2. 与Unix域套接字甚至SYSV IPC相比,现代系统,特别是Linux和* BSD,对使用TCP / IP没有明显的损失。
  3. 您可以使用许多库和框架来使用通过TCP / IP进行通信的应用程序。
  4. 我不会使用TCP / IP在两个“程序”之间进行通信的唯一情况是它们实际上是线程而不是单独的程序。