UDP C套接字:多个套接字共享单个端口

时间:2011-03-30 04:53:32

标签: c linux sockets udp gnu

我正在用GNU / Linux上的C编写一个程序,它使用UDP在程序的各个实例之间传递消息,可以在一台机器上,也可以在网络上传递。程序的每个实例都有自己独特的内部应用程序层地址,用于区分在单个机器上运行的实例(从而共享IP地址)。目前,整个系统在单个UDP端口上进行通信。

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

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

  1. 将一台计算机上的所有程序实例绑定到同一个公共协议端口
  2. 收到消息时,每个实例都将使用recv并设置MSG_PEEK标志,以确定消息的应用层地址是否与实例的内部地址匹配。
  3. 对于地址匹配的给定计算机上的单个实例,对recv的常规调用将从输入队列中删除该消息,以供相应实例处理。
  4. 基本上,我希望使用UDP作为通用通信介质,在应用层发生更具体的寻址。

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

    基本上,我希望将消息“广播”到一组共享单个IP地址的实例,并让他们在应用层理清消息所属的对象。

    思想?

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

如果它是客户端/服务器风格的应用程序,则客户端无需绑定。

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