C++ UDP接收

C++ UDP Receving

我有一整天都在努力解决的问题。情况如下:

  1. 我有一个服务器列表 - 假设有 10 个不同的服务器。
  2. 我想使用 sendto 命令向所有 10 个服务器发送提案广播消息。
  3. 然后我想监听并等待 10 个服务器以 ACK + 一些消息响应。
  4. 一段时间后,使用已响应服务器的数据超时。 (时间将根据请求量而变化)

我想使用 UDP 使其独立于连接,但也担心如果我一次发出所有消息,我可能会错过一条消息,因为我没有阻塞 revfrom 行,直到发送完所有消息。

我可以在每次发送后等待,但从广播的角度来看这似乎效率不高。

我也可以先设置一个监听线程,然后 运行 sendto 在一个单独的线程上,但是监听器(即整个程序)在 main 之外的另一个线程上。

所以我的问题有两个:考虑到我正在尝试做的事情,这些方法中的哪一个(如果有的话)看起来最合适?其次,socket上有没有队列。比如说它不是 10 台,而是 1000 台服务器——如果一条消息在它还没有准备好接收的时候进来,这条消息会被丢弃吗?

我愿意接受有关其他实施方式的建议。

提前致谢!

现在大多数个人计算机都位于防火墙后面,防火墙会阻止任何传入的 UDP 数据包 --- 事实上,现在大多数个人计算机也位于 NAT 转换层后面,甚至没有自己的 Internet 可路由 IP地址。在担心由于时间问题而错过偶尔传入的 UDP 消息之前,我会担心这一点。

就是说,如果您的客户端 运行 在开放的 Internet 上(或者在配置为允许 UDP 数据包进入的防火墙后面),计时问题并不是真正的问题,因为作为 socket() 调用的一部分,网络堆栈为每个套接字分配一个传入数据缓冲区。在套接字上成功调用 bind() 后,到达该套接字端口的任何 UDP 数据包都将放入套接字的传入数据缓冲区,准备好在下次调用 [=12 时移交给您的代码=].重要的是,无论您的线程当前是否在 recvfrom() 调用中,都会发生这种缓冲。

传入数据缓冲区可能会被填满(它的大小有限,通常在 64KB 左右);在这一点上,任何额外的传入 UDP 数据包都将被丢弃。避免这种情况的通常方法是确保您尽快调用 recvfrom(),或者如果这还不够,您可以使用 setsockopt() 告诉网络堆栈创建套接字的传入数据缓冲区更大。

与此同时,您对 sendto() 的调用可能会很快完成,因为 sendto() returns 一旦数组中的数据被复制到套接字的传出数据缓冲区中。特别是,sendto() 不会 等待字节通过网络,或者(通常)甚至等待字节到达您的网卡。在最坏的情况下,它可能会阻塞,直到传出数据缓冲区中有足够的空间将数据放在那里;传出数据缓冲区始终以您的网络设备的线速消耗。