c - Linux UDP 套接字/端口重用

标签 c linux multithreading sockets udp

我正在试验 Linux UDP 套接字。我有一台服务器和客户端通过以下方式相互交谈。

服务器:在端口 X 上向其子网中的所有 IP 发送广播公告。

客户端:通过将单播消息发送回服务器来响应公告。此消息直接发送回端口 X。

在服务器上,我有一个定期发送通知的线程。我现在想添加更多代码来接收来自客户端的响应以及向特定客户端发送单播消息。下面概述了我为服务器提出的方案。

线程 1

  • 在 socket_a 上广播,使用 setsockopt() 设置 SO_BROADCAST。在端口 X 上发送广播公告。

线程 2

  • 使用 socket_b 从端口 X 读取数据。由于代码当前结构的限制,该线程无法访问 socket_a。请注意,该端口与 socket_a 共享。调用 bind() 以读取此套接字上的数据。

线程 3

  • 使用端口 X 上的 socket_b 向特定客户端发送单播数据。请注意,套接字和端口均与线程 2 共享,并且该端口在所有三个线程和两个套接字之间是通用的。

以下是我的问题(请耐心等待,我对 unix 套接字编程还很陌生):

  1. 我需要在两个套接字之间进行任何锁定,还是在操作系统中进行处理?也就是说,我能否同时向两个套接字发送数据而不会发生一些奇怪的冲突,因为它们都使用相同的端口?

  2. 我是否需要担心线程 2 接收到由任一“发送方”线程发送的数据?我该如何防止这种情况?

  3. 是否需要启用任何选项才能使这项工作正常进行?在单播套接字 (socket_b) 之前设置广播套接字 (socket_a) 是否重要?

  4. 我应该在端口 X 上创建一个专用的“接收”套接字吗?也就是说,拥有一个仅用于接收数据的套接字是否有意义?这是唯一会调用 bind() 的套接字。

  5. 考虑到所有三个线程都使用同一个端口,是否还有任何其他问题我应该担心?不幸的是,这是我正在处理的一个约束。如果上述方案无法实现,我可能不得不重新审视我的单端口设计。

预先感谢您的帮助。

最佳答案

我认为这行不通。 当您多次将 UDP 套接字绑定(bind)到同一个 ip+端口时,发往该 ip+端口的数据包将被传送到任何套接字。因此,对等点对您的 ip+port 的单播回复可能会传送到三个套接字中的任何一个。当锁定这样的数据包时,这种行为是非常合乎逻辑的:从操作系统的角度来看,udp 数据包包含一个源 ip+端口和一个目标 ip+端口。并且因为您所有的套接字都只绑定(bind)到目标 ip + 端口,仅此而已,所以任何套接字都可能在最后得到回复。

因此,您可能需要围绕单个套接字重构您的应用程序,该套接字将用于单播和广播,并将接收所有回复并处理它们。如果你坚持使用多个线程,你可以使用同一个套接字从所有线程发送而不锁定,但你应该只在一个线程中接收。在这个线程中,您需要确定数据包的种类,然后您可以将其“交给”正确的线程。

关于c - Linux UDP 套接字/端口重用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21179042/

相关文章:

c - sizeof struct 小于 4 B 被报告为实际

C# 应用程序创建许多连接线程,MySQL

c - 在 time.h 中找不到 timespec

c - 用于在运行时操作机器代码的库?

java - Hadoop - 资源是 <memory :0, vCores:0>

linux - web文件的x可执行权限是什么?

linux - Linux 上的 Cygnal Integrated Products 串口

android - 为什么我的线程不会死掉并导致内存泄漏?

ios - 指定函数 block 是异步与同步的模式

c++ - 自行卸载的 Linux 共享库