【问题标题】:UDP C Sockets: Multiple Sockets Sharing Single PortUDP C 套接字:多个套接字共享一个端口
【发布时间】:2011-07-25 19:37:08
【问题描述】:

我正在 GNU/Linux 上用 C 语言编写一个程序,它使用 UDP 在程序的各个实例之间(在单台机器上或通过网络)通信消息。该程序的每个实例都有自己唯一的内部应用程序层地址,用于区分在单个机器上运行的实例(并因此共享一个 IP 地址)。目前,整个系统在单个 UDP 端口上进行通信。

这在运行在不同机器上的程序实例之间运行良好,因为它们都具有唯一的 IP 地址,因此具有唯一的套接字连接。问题是在一台机器上运行多个实例。在这种情况下,只有程序的第一个实例获得了套接字连接,而其他实例则失败,因为该端口已在使用中。

有没有办法将多个数据报套接字绑定到一个端口?我意识到这通常是不可取的,但由于我有唯一的应用程序层地址可以用来解决歧义,所以在这种情况下会有所帮助。本质上,我希望能够做到以下几点:

  1. 将单台机器上的所有程序实例绑定到同一个通用协议端口
  2. 收到消息后,每个实例将使用设置了 MSG_PEEK 标志的 recv 来确定消息的应用层地址是否与实例的内部地址匹配。
  3. 对于给定计算机上地址匹配的单个实例,对 recv 的常规调用将从输入队列中删除消息,以供适当的实例处理。

从本质上讲,我希望将 UDP 用作通用通信介质,并在应用层进行更具体的寻址。

在 GNU C 中有标准的方法吗?我意识到我可以编写一个顶级管理程序来监听套接字上的所有消息并将它们重新路由到适当的实例,但这似乎不必要地复杂,并且会破坏程序在网络上的多个实例与共享单个实例的相同操作知识产权。我也知道我可以使用多个端口,但这增加了为每个实例分配一个单独的空闲端口并在整个实例网络中跟踪这些端口的需要。

本质上,我希望将消息“广播”到共享单个 IP 地址的一组实例,并让它们在应用层整理出消息属于谁。

想法?

【问题讨论】:

    标签: c linux sockets udp gnu


    【解决方案1】:

    您可以使用 setsockopt(SO_REUSEPORT) 进行此类绑定,但我认为这无济于事。您将有几个套接字,每个套接字都有自己的数据包队列,每个数据包只会进入一个队列。 MSG_PEEK 没有用。

    顶级实例将消息重新路由到不同的消费者看起来是正确的解决方案。

    【讨论】:

      【解决方案2】:

      您不能使用绑定到唯一 ip/端口组合的多个套接字。

      使用一些消息队列/消息传递接口,忘记 UDP。 比如看0MQ(zeromq)http://www.zeromq.org/

      【讨论】:

        【解决方案3】:

        如果是客户端/服务器风格的应用,客户端不需要绑定。

        当服务器响应尚未绑定的客户端时,它将响应客户端发送时操作系统随机选择的源端口(无绑定)。 然后客户端从未绑定的端口读取。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-02-04
          • 1970-01-01
          • 2018-05-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多