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

发布于 2024-10-27 20:29:03 字数 847 浏览 1 评论 0原文

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

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

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

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

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

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

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

想法?

I'm writing a program in C on GNU/Linux that uses UDP to communicate messages between various instances of the program, either on a single machine, or across a network. Each instance of the program has it's own unique internal application layer address that it uses to differentiate between instances that run on a single machine (and thus share an IP address). Currently, the whole system communicates on a single UDP port.

This works fine between instances of the program running on separate machines, as these all have unique IP addresses, and thus unique socket connections. The problem is running multiple instances on a single machine. In this case, only the first instance of the program gets a socket connect and the others fail since the port is already in use.

Is there a way to bind multiple datagram sockets to a single port? I realize this is not normally advisable, but since I have unique application layer addresses that I can use to resolve the ambiguity, it would be helpful in this case. Essentially, I want to be able to do the following:

  1. Bind all instances of the program on a single machine to the same common protocol port
  2. When a message is received, each instance will use recv with the MSG_PEEK flag set to determine if the message's application layer address matches the instance's internal address.
  3. For the single instance on a given machine where the addresses match, a regular call to recv will remove the message from the input queue for processing by the appropriate instance.

Essentially, I wish to use UDP as a common communication medium with more specific addressing occurring at the application layer.

Is there a standard way of doing this in GNU C? I realize that I could write a top level governing program to listen to all messages on the socket and reroute them to the appropriate instance, but this seems unnecessarily complicated, and breaks the program operating identically with multiple instances across a network vs across a shared single IP. I also know I could use multiple ports, but this adds the need to assign each instance a separate free port and keep track of these across the entire network of instances.

Essentially, I wish to "Broadcast" a message to a group of instances sharing a single IP address and let them sort out who the message belongs to at the application layer.

Thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

半夏半凉 2024-11-03 20:29:03

您可以使用setsockopt(SO_REUSEPORT) 进行此类绑定,但我认为这没有帮助。您将有多个套接字,每个套接字都有自己的数据包队列,并且每个数据包仅进入一个队列。 MSG_PEEK 没有任何好处。

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

You can do such binding with setsockopt(SO_REUSEPORT), but I think it would not help. You will have several sockets, each with its own packet queue, and each packet will go in one queue only. MSG_PEEK will do no good.

Top-level instance rerouting messages to different consumers looks like right solution.

不疑不惑不回忆 2024-11-03 20:29:03

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

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

You can't use the multiple socket bound to a unique ip/port combination.

Use some message queue / message passing interface, and forget about UDP.
For example, see 0MQ (zeromq) http://www.zeromq.org/

一直在等你来 2024-11-03 20:29:03

如果它是客户端/服务器样式的应用程序,则客户端不需要绑定。

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

If it's a client/server style app, the client side need not bind.

When the server responds to the client that hasn't bound it will respond to the source port which will be randomly chosen by the OS when the client sends (without bind).
The client then reads from the unbound port.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文