【发布时间】:2018-04-20 16:30:17
【问题描述】:
我有一个嵌入式设备,它直接通过以太网连接到我的 PC。
设备通过 UDP 将音频流式传输到 pc,它发送 4096 字节的 UDP 数据包。
鉴于,以太网的MTU 是 1500 字节,数据包将被分段。
在 PC 上,我有一个 C# 程序,它尝试接收数据包并对其进行解码。 UDP 接收器在有效载荷小于 1500 字节时可以很好地接收数据包,但无法接收碎片数据包。
我通过Wireshark监控了传入的数据包,我可以看到数据包没有任何失败也没有丢弃。
我不知道问题出在我的代码中,还是 C# 套接字无法接收此类数据包。在这两种情况下,解决方案是什么?
第一次尝试:(使用 Socket)
Socket sokcet = new Socket(SocketType.Dgram, ProtocolType.Udp);
IPEndPoint ep = new IPEndPoint(IPAddress.Any,5222);
sokcet.Bind(ep);
int counter = 0;
while (true)
{
if(sokcet.Available > 0){
byte[] bytes = new byte[sokcet.Available];
int receivedBytes = sokcet.Receive(bytes);
string print = String.Format("Packet Received : {0},{1}", receivedBytes, counter);
Console.WriteLine(print);
}
}
第二次尝试:(使用 UDPClient)
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, listenPort);
UdpClient listener = new UdpClient(listenPort,AddressFamily.InterNetwork);
while (!done)
{
byte[] bytes = listener.Receive(ref groupEP);
}
它们都不适用于大于 1500 字节的数据包。
更新 1: 我在 Loopback(127.0.0.1) 中测试了这个场景,我可以很好地接收到 4k UDP 消息。
更新 2:
@Evk我从另一台通过交换机和路由器连接到我的电脑上测试了这个场景。现在我确信 C# 没有任何问题。不确定操作系统(win7 Ultimate 64x)。
我的嵌入式设备使用 LWIP,当用户使用 LWIP 发送大型 UDP 数据包时,有一些类似情况的报告。但我不确定这是我的情况。
我什至检查了 UDP 数据包的源地址和目标地址、校验和……但我无法弄清楚操作系统为什么会丢弃我的数据包。有没有什么工具可以分析网络包来判断是否有问题?
【问题讨论】:
-
发送数据时,接收方必须知道消息的结尾在哪里,并读取到结尾。所以使用以下之一 1) Ascii :用已知字符终止数据,不在消息中,如 '\n' 2) Ascii 或 Binary :将字节数添加到消息的开头 3) Ascii 或 Binary :使用固定长度的消息。
-
问题不在于长度变化,问题在于数据包负载超过 1500 字节时 'sokcet.Receive(bytes);'在第一个例子中和'listener.Receive(ref groupEP);'在第二个例子中不要执行。
-
“当发送数据时,接收者必须知道消息的结尾在哪里并且读到结尾”——@jdweng 的这句话在这里完全不相关,因为你正在使用UDP,一种为您构建消息的协议。您可以放心地忽略他们的评论。至于您的实际问题,当没有一个好的minimal reproducible example 可以可靠地重现问题时,很难提供任何有用的建议,更不用说一个好的答案了。假设您的代码运行良好,那么您的问题更有可能在于网络配置而不是代码本身。
-
@jdweng UDP 是面向消息的协议(与面向流的 TCP 不同)。 UDP中的“D”是可以被认为是消息的数据报。您所说的对于 TCP 是正确的,但对于 UDP 不是。当您通过 UDP 发送某些内容时 - 您将其作为单个“块”发送。当您通过 UDP 接收某些内容时 - 您再次将其作为单个块进行。你可以看到 UdpClient 有简单的
Receive方法,它返回字节数组而不需要你指定大小。 -
@jdweng UDP 片段的最大大小略小于 64K 字节。它可以在多个 IP 数据包上分段,但将在接收端由网络堆栈重新组装。如果数据报的任何片段丢失 - 整个数据报都会丢失。你永远不会在你的套接字中收到部分数据报。
标签: c# sockets networking udp