我对UDP的理解是,虽然有MTU大小的限制,但如果数据报超过MTU,它将在IP层被分段,作为单独的数据包传输,然后在接收端重建。如果其中一个片段被丢弃,UDP层将丢弃整个数据报。如果一切就绪,IP层将重新构造数据报,UDP应将其作为一个整体接收。
然而,这不是我正在经历的行为。下面是一个简单的服务器循环
var udp = new UdpClient(port);
while (true) {
IPEndPoint remote = new IPEndPoint(IPAddress.Any, 0);
byte[] payload = udp.Receive(ref remote);
Console.WriteLine($"Received {payload.Length}, IP: {remote}");
}通过netcat发送数据的2999 bytes如下
head -c 2999 /dev/urandom | nc -4u -w1 localhost 8999服务器循环使用大小为1024、1024和951字节的有效负载接收三次。从2*1024 + 951 = 2999开始,似乎很明显我想发送的数据实际上已经发送了,但是UdpClient将它作为三个不同的数据报接收。
这似乎与UDP层作为一个整体处理数据报的事实不一致。当直接使用UDP时,是否应该实现自己的片段重建逻辑?或者,有没有办法只接收完整的数据报?
发布于 2017-10-05 01:12:45
您对UDP的理解确实是正确的。只要所有碎片都到达目的地,该协议就会透明地为您处理碎片和重组。我最初认为head可能会将您的数据以1024字节块的形式传递给netcat,但事实并非如此。
这实际上是相反的场景:在您的系统上,netcat以1024字节的块的形式从stdin读取数据,并每次生成一个新的UDP包。似乎netcat最适合用于处理连续的数据流,这些数据流大多与较低层如何打包无关。
欲了解更多信息,请访问this StackOverflow question。
https://stackoverflow.com/questions/46560098
复制相似问题