【问题标题】:why we cannot accept() a socket on some process and recv() data from its child?为什么我们不能接受()某个进程上的套接字和来自其子进程的recv()数据?
【发布时间】:2011-12-10 15:03:07
【问题描述】:

我正在尝试在 Linux 上实现一个简单的 Web 服务器,它连接到客户端(浏览器),接收来自客户端的一些请求(例如 GET),然后用所需文件发回响应。我正在使用套接字通信。我想在服务器启动时创建一个工作进程(子)池,其工作是处理传入的请求。父进程必须 accept() 传入请求并将其文件描述符发送到其中一个工作进程以处理它,并将响应与请求的文件一起发送给客户端。

我遇到的问题是,当我accept()请求并将其发送到工作进程时,recv()read()函数返回-1,这意味着发生错误:

非套接字上的套接字操作

但是当我尝试在父进程中使用recv()read() 函数时,它们工作得很好,并返回接收到的字节数。

我该如何解决这个问题?

PS:我正在使用共享内存将文件描述符从父进程传递给工作进程(子进程),并且我正在使用信号量来管理哪个工作进程将处理请求支持>


编辑:

实际上,这是一个项目分配,其中一个规范是通过共享内存发送文件描述符。但是,我可以发送文件描述符的指针吗?

【问题讨论】:

  • 您可以使用关键字“Pre forked”找到更多信息。 Similar question

标签: c linux sockets process


【解决方案1】:

您不能通过共享内存发送文件描述符,AFAIK。所以你所做的实际上是向工作进程发送一个小整数。

可以做的是通过 Unix 域套接字发送文件描述符,使用 sendmsg 和辅助数据。这听起来有点像魔法(哎呀,它有点像魔法)但它在 Unix 中是相当标准的,所以它应该可以工作。

【讨论】:

  • 这不会导致同样的结果吗?或者在通过域套接字传递这些东西时是否有一些额外的处理?
  • @Mario 不。操作系统发挥了它的魔力,它实际上传递了对文件描述符的引用。您要搜索的是“传递文件描述符”。
  • 其实这是一个项目分配,其中一个规范是通过共享内存发送文件描述符。但是,我可以发送文件描述符的指针吗?
  • @Eng.Fouad 正如我在回答中所说,AFAIK 发送文件描述符的唯一方法是通过 Unix 域套接字。
【解决方案2】:

您的工作人员是另一个进程还是只是另一个线程?我很确定您的描述符在创建/拥有它们的过程之外将无效。它应该有点像本地指针。它们仅对创建它们的进程有效(由于虚拟内存寻址等)。

【讨论】:

  • 工作进程是主进程的子进程(接受请求)
【解决方案3】:

也许更好的方法是在 fork 之前创建服务器套接字, 并让子进程调用accept()。 所以父进程不需要将接受的套接字传递给子进程。

当多个子进程正在等待来自同一端口的连接,并且客户端打开到该端口的连接时,内核会将新连接提供给其中一个子进程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多