我正在 GNU/Linux 上用 C 编写一个程序,它使用 UDP 在程序的各个实例之间(在单台机器上或通过网络)传递消息。该程序的每个实例都有自己唯一的内部应用层地址,用于区分在一台机器上运行的实例(因此共享一个 IP 地址)。目前,整个系统在单个 UDP 端口上进行通信。
这在不同机器上运行的程序实例之间运行良好,因为它们都有唯一的 IP 地址,因此也有唯一的套接字连接。问题是在一台机器上运行多个实例。在这种情况下,只有程序的第一个实例获得套接字连接,其他实例失败,因为端口已被使用。
有没有办法将多个数据报套接字绑定(bind)到一个端口?我意识到这通常是不可取的,但由于我有唯一的应用程序层地址可以用来解决歧义,这在这种情况下会很有帮助。本质上,我希望能够执行以下操作:
- 将单台机器上的所有程序实例绑定(bind)到同一个公共(public)协议(protocol)端口
- 收到消息时,每个实例将使用设置了 MSG_PEEK 标志的 recv 来确定消息的应用层地址是否与实例的内部地址匹配。
- 对于地址匹配的给定机器上的单个实例,对 recv 的定期调用将从输入队列中删除消息,以供适当的实例处理。
本质上,我希望将 UDP 用作通用通信介质,并在应用层进行更具体的寻址。
在 GNU C 中是否有执行此操作的标准方法?我意识到我可以编写一个顶级管理程序来监听套接字上的所有消息并将它们重新路由到适当的实例,但这似乎不必要地复杂,并且破坏了程序在网络上与多个实例相同地运行与在共享单个实例上运行知识产权。我也知道我可以使用多个端口,但这增加了为每个实例分配一个单独的空闲端口并在整个实例网络中跟踪这些端口的需要。
本质上,我希望将一条消息“广播”给共享单个 IP 地址的一组实例,并让它们在应用程序层理清消息属于谁。
想法?
最佳答案
您可以使用 setsockopt(SO_REUSEPORT) 进行此类绑定(bind),但我认为这无济于事。您将有多个套接字,每个套接字都有自己的数据包队列,每个数据包只会进入一个队列。 MSG_PEEK 不会有任何好处。
顶级实例将消息重新路由到不同的消费者看起来是正确的解决方案。
关于c - UDP C 套接字 : Multiple Sockets Sharing Single Port,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5482004/