我有一些利用winsock的UDP接收代码,特别是AF_INET,SOCK_DGRAM和IPPROTO_UDP。 recv调用存在于循环中,该循环读取直到接收到所有数据为止。问题是我每次只会得到部分数据。此外,我什至不需要循环,因为我可以看到所有数据都存在于单个数据包中。在wireshark中,我看到实际数据长度为299字节。 Wireshark成功查看了整个数据包,因此我知道数据包发送方工作正常。
使用我的Windows UDP代码,我只能得到8个字节,直到我的receive方法返回为止。我可以看到UDP代码在看到00字节时正在停止。 Wireshark可以读取过去的00个字节,但Windows udp recv无法读取过去的00个字节。 Windows似乎以00结尾,因此得出的结论是该数据包只有8个字节。
我看了wireshark中的标头,发现指定的长度是正确的,所以我对为什么只读取8个字节感到非常困惑。谢谢您的提前帮助。
这是我的接听电话,供参考:
int ret = recv(socket, buffer, 1500, 0);
ret变为8,分配给1500个字节的缓冲区仅填充8个字节
答案 0 :(得分:0)
UDP是面向消息的,而不像TCP那样面向流。
在UDP中,如果出现以下任一情况,则recv()
返回8个字节的 only 方式是:
您将len
参数设置为> 8
,并且会接收到一个数据报,该数据报恰好包含8个字节。
您将len
参数设置为== 8
,并接收到包含8个以上字节的数据报。
假设您将len
设置为1500,那么唯一的可能性就是接收到的数据报中只有8个字节,而不是您声称的299个字节。
与TCP不同,在UDP中,您不能分段读取数据报,而读取则是一项全有或全无的操作(除非您窥视未执行的数据)。在UDP中,recv()
/ recvfrom()
一次读取整个数据报,如果提供的缓冲区太小而无法接收数据(在这种情况下不是),则发生WSAEMSGSIZE
错误将被报告,并且数据将被截断,并丢弃缓冲区中不适合的其余数据。
您描述的00
空字节对recv()
/ recvfrom()
读取整个数据报的能力没有任何影响。数据报带有有效载荷长度,并且recv()
/ recvfrom()
将读取该有效载荷长度或指定的缓冲区大小,以较小者为准,而与实际有效载荷内容无关。
因此,在您的代码中,recv()
可能根本没有收到您期望的数据报。
例如,要完全在UDP中使用recv()
,必须首先使用connect()
UDP套接字将其与特定的对等IP /端口相关联,从而允许recv()
忽略来自其他对等方的入站数据报(并使send()
将数据报发送到特定对等方)。也许您正在connect
将UDP套接字连接到错误的对等设备,从而读取了用于其他目的的数据报。或者,也许您是connect
正在访问正确的对等设备,并且它实际上正在发送您不期望的8字节数据报。
由于您没有提供有关设置的任何上下文信息,因此涉及的对等方,所涉及的协议,Wireshark捕获都什么也没有,实际上,任何人都无法通过任何方式来诊断您的情况肯定。但是,我上面所描述的将解释您所描述的症状。如果您并非如此,则需要编辑问题以提供更多详细信息。