在C / Unix中的Socketpair()

我有两个应用程序在同一个系统上,我需要来回沟通。 从我的研究,我相信这被称为进程间通信和使用socketpair()是我的问题最好的方法。

我正在把我的头发撕掉(字面意思)试图开始用C中的socketpair()创build套接字。从我所了解的来说,套接字是一个非常复杂的话题,而我作为新手C程序员肯定没有帮助。

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

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

您只能在创建两个进程的地方使用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 */ } 

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


如果你想要两个独立的程序进行通信(例如,你有一个叫做客户端的可执行文件和一个叫做服务器的可执行文件),你不能使用这个机制。 相反,你可能会:

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

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

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

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

对于两个进程之间的通信,是的,进程间通信或IPC是你应该寻找的。 套接字只是用于通信的方法之一,如果您必须实现一对多连接,套接字才是有用的。 意思是一个服务器进程以请求 – 响应方式与许多客户进程通信。 由于您是IPC的新手,可以理解的是套接字地址和所涉及的细节可能看起来难以掌握。 (尽管在适当的时候你会发现它们很容易:-))

对于你的问题,我建议你使用更简单的IPC机制,如Pipe,FIFO,Message Queue。 我不知道你是如何得出使用socketpair的结论。 由于您没有提及IPC的设计或IPC类型,因此您需要根据使用级别进行操作,强烈建议您在某本书或Internet上查看Pipe或FIFO示例代码。 他们应该看起来更容易实现和工作比插座更快。

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

  1. Web上有很多教程和其他信息,描述如何执行TCP / IP
  2. 与Unix域套接字甚至SYSV IPC相比,现代系统,尤其是Linux和* BSD,对于使用TCP / IP并没有什么重大的损失。
  3. 有许多库和框架可以用于通过TCP / IP进行通信的应用程序。

我不会使用TCP / IP在两个“程序”之间进行通信的唯一情况是,它们确实是线程而不是单独的程序。