UDP recv / recvfrom多个发件人

时间:2012-01-05 19:44:25

标签: c++ udp recv

美好的一天,

我正在使用VC ++开发一个应用程序,它在Windows XP上使用UDP协议和winsock进行通信。以前我已经能够假设该工具接收的所有数据包都来自单个目标。但是我现在正在接收广播。监听线程的开销很小,应该将所有时间都花在下面一行:

rv = recvfrom(socket, 
              p_buffer_p, 
              p_size,
              0,
              (sockaddr*)&clientService_in, //This is set to do a broadcast recv
              &SenderAddrSize);

我的问题是我是否可以假设我从recvfrom返回的缓冲区来自单个目标。也就是说,发送应用程序中的1个调用发送应用程序等于从接收应用程序中的recvfrom返回1?或者多个发件人的多个发送可以合并为1?

我假设来自目标的单个发送不能从recvfrom分成多个返回。我一直都是这样,从来没有遇到任何问题。

还有一件事,它是一个SOCK_DGRAM类型的套接字。

2 个答案:

答案 0 :(得分:6)

不,无法拆分UDP消息。他们在被送出时到达。此外,不会连接多个UDP消息。

因此,N发送消息对应于N个recvfrom呼叫。

引自wiki

  

数据报 - 单独发送数据包并进行检查   诚信只有在他们到达时。数据包有明确的界限   在收到时很荣幸,这意味着在接收器上进行读取操作   socket将生成最初发送的完整消息。

答案 1 :(得分:2)

你是正确的,一次调用recvfrom()将返回最多一个UDP数据报。 但不能保证每个数据报都会实际到达。

特别是,如果您发送的UDP数据报太大,它可能会在网络级别(碎片)被分割成碎片,这会增加数据报被丢弃的可能性(因为丢失任何碎片会导致丢失)整个)。您没有在应用程序级别看到碎片,因为网络级别会为您重新组装数据包。

事情变得非常棘手,因为不可能提前知道究竟有多大。有各种各样的算法可供查找,但它们都相当于试验和错误。更糟糕的是,防火墙,路由器和操作系统可以(并且通常会)随着时间的推移改变其对碎片数据报的行为。可能存在这样的情况:特定大小或组合的数据包将始终被丢弃,因为它违反了某些防火墙规则。

所以永远不要假设sendto()必然会产生recvfrom(),并尝试保持数据报的小(小于1400字节是相当安全的,小于512字节是非常安全的)。