【问题标题】:How does connect()'ing a bind()'ed socket in a forked process affect the socket in the parent?在分叉进程中连接()绑定()的套接字如何影响父级中的套接字?
【发布时间】:2022-01-06 19:34:14
【问题描述】:

我正在通过 UDP(uni assignment)实现一个可靠的、面向连接的应用程序。要求服务器在收到客户端的初始数据包并确认后,创建一个新的工作进程。工作进程应该有一个专用于这个特定客户端的套接字。

现在我看到了三种实现方式。

  1. 服务器有一个socket,我们称之为listener_socket,绑定到指定端口,等待请求。然后,我可以在子进程中,connect() 这个套接字到客户端地址。
  2. 或者,我可以完全关闭子进程中的listener_socket,然后打开一个全新的套接字connection_socket,将其绑定到端口并连接到客户端。
  3. 或者,在新端口上打开一个新套接字,并编写客户端代码以在连接的剩余时间内处理这个新端口。

我不确定的(关于选项 1)是将listener_socket 连接到客户端如何影响父服务器中的原始listener_socket。它会阻止父级从其他客户端接收更多消息吗?如果不是,为什么?它们最终不是都指向同一个套接字吗?

至于选项 2,这让我非常期待“地址已在使用中”。是否有类似路由器的功能(即最长匹配前缀)将数据报传递到“最合适的”套接字? (好吧,TCP 已经在 accept() 中做到了这一点,所以这个逻辑不太可能被复制到 UDP 中。)

关于选项 3,我认为它的效率很低,因为它意味着我应该为每个客户端使用一个新端口。

那么有人可以建议使用哪种方法,或者是否还有其他我不知道的方法? 谢谢。

【问题讨论】:

  • 您谈论的是父母和子女——至少对我而言——建议单独的“分叉”进程(forkexec 等),但您也谈论线程。你能澄清一下在这种情况下你所说的“父母”和“孩子”是什么意思吗?抱歉,如果我遗漏了什么。
  • @G.M.啊,抱歉,我只是将线程用作进程的同义词,因为我忘记了 POSIX 线程。我的意思是每个进程都有自己的资源副本。我的错!

标签: c linux sockets udp connection


【解决方案1】:

我不确定的(关于选项 1)是将 listener_socket 连接到客户端如何影响父服务器中的原始 listener_socket。它会阻止父级从其他客户端接收更多消息吗?

是的。

如果不是,为什么?它们最终不是都指向同一个套接字吗?

是的,当父级分叉子级时,子级会收到父级所有打开文件描述符的副本,这些副本指的是由内核管理的打开文件描述。因此,这些打开的文件描述在父母和孩子之间共享。因此,如果子connect()s 将套接字连接到客户端,那么父子都会看到这样的效果

如果套接字sockfd的类型是SOCK_DGRAM,那么[指定地址]是默认发送数据报的地址,是接收数据报的唯一地址

Linux manual page;强调)

至于选项 2,这让我非常期待“地址已在使用中”。是否有一些类似于路由器的功能(即最长匹配前缀)将数据报传递到“最合适的”套接字?

是什么让一个插座比另一个更合适?无论如何,没有。 UDP 端点仅由地址和端口标识。

关于选项 3,我认为它的效率很低,因为它意味着我应该为每个客户端使用一个新端口。

相对于什么效率低下?是的,您的选项 (3) 需要为每个客户端指定一个单独的端口,但您没有提出任何其他可行的替代方案。

但这并不是说没有其他可行的替代方案。如果您不想协商一个单独的端口并为每个客户端打开一个单独的套接字(例如,这是 FTP 可以运行的方式之一),那么您不能依赖每个客户端的 UDP 套接字。在这种情况下,服务的所有传入流量都必须转到同一个套接字。但是您可以让在该套接字上接收消息的进程根据消息的源地址和端口将每个消息分派给适当的合作进程。您应该能够让这些进程都通过同一个套接字发送响应。

可以通过多种方式设置此类系统的详细信息。它们都有一个限制,即接收所有消息的一个进程可能会成为瓶颈,但实际上,我们谈论的是 I/O。主要瓶颈很可能在网络级别,而不是在接收过程中。

【讨论】:

    【解决方案2】:

    如果分叉后子进程中的套接字与父进程中的套接字相同,则它们都反映了相同的内核套接字。由于绑定和连接是在内核套接字上完成的,因此对子套接字的任何更改也会影响父套接字。因此有必要创建一个新的(独立的)连接套接字。

    但套接字需要绑定到与侦听器套接字相同的本地地址和端口,因为这是对等方期望数据包来自的地方以保持相同的 UDP 关联。

    【讨论】:

      猜你喜欢
      • 2011-08-26
      • 2015-01-16
      • 1970-01-01
      • 2016-02-26
      • 1970-01-01
      • 2011-02-27
      • 2016-06-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多