无法在大于10K的UDP上发送图像

时间:2009-08-10 00:55:16

标签: c# udp

我正在尝试开发一个客户端/服务器应用程序,客户端将把图像发送到服务器。

案例1:

服务器在路由器后面的一台计算机上运行,​​客户端在另一台不同路由器后面的另一台计算机上运行。由于此通信将在WAN(公共IP)上进行,因此端口将在服务器端路由器上转发,以便服务器可以轻松地在该端口上接收传入的UDP数据报。

UDP的最大传输单元(MTU)大小为64KB。这意味着UDP套接字应该能够传输任何大小小于或等于65,536字节的东西。在我正在开发的应用程序的情况下,客户端只能发送10-13k的图像(UDP数据报)。如果我尝试传输大小超过10Kb的图像,服务器将无法接收它,服务器端UDP套接字将始终处于(接收)阻塞模式。

案例2:

服务器在路由器后面的计算机上运行,​​客户端在同一台路由器后面的计算机上运行。这意味着客户和服务器位于同一局域网中。甚至客户端和服务器共享相同的局域网客户端正在服务器的公共IP上发送图像(UDP数据报)。在这种情况下,服务器能够接收任何大小的UDP数据报,最高可达64K,这正是我期待的应用程序。

我尝试在不同的远程PC上运行我的客户端,但结果是一样的。服务器无法接收大于10-13Kb的UDP数据报。如果有人能帮助我处理这种情况,他将不胜感激。

链接到代码: http://pastebin.com/f644fee71

感谢您对项目的了解。 的问候,

与Atif

2 个答案:

答案 0 :(得分:11)

尽管IP层可能允许最大64k的UDP数据包,但我认为您会发现最大的“野外”UDP数据包大小将限制在源和目标之间设备的最小MTU。

标准以太网MTU约为1500字节。一些设备支持高达~10千字节的“巨型”帧以提高性能。但是,这种事情通常不会通过公共互联网支持,只能在局域网上支持。

IP层可以对UDP数据包进行分段(除非在数据包中设置了无分段位)。但是,如果按顺序接收每个片段(或在特定时间限制内无序),则接收者将仅接收和整理分组。否则它将丢弃该数据包。

也可能是源和目标之间的所有设备都不支持发送设备的帧大小。我遇到过需要将路由器上的MTU降低到~1450字节的情况,因为中间路由器在1500处丢弃数据包。这是由于MTU发现无法可靠地工作。即,发送设备无法确定其到达目的地的路径上的设备的MTU是什么。在该路径中的某个地方,设备将丢弃它认为太大的数据包。

对你正在做的事情来说,UDP是一个非常糟糕的主意。你最好使用TCP。

如果您担心TCP连接设置/拆除的性能,请尽可能长时间保持连接。

当您不太关心目标是否收到数据包时,UDP只是一个很好的协议来传递数据。交货不保证。在所有其他情况下使用TCP。

如果您决定使用UDP,则必须在协议中实施path MTU discovery并捕获路由器/防火墙不会阻止“需要分片”的ICMP数据包。否则他们不应该使用TCP也不行。但就像我说的那样,我曾经看过过去需要碎片的ICMP数据包被阻止或丢弃的情况,我不得不手动调整自己的MTU。

答案 1 :(得分:0)

UDP是一种不可靠的数据报协议。数据包无法保证到达目的地,或者按照您发送的顺序到达。

此外,当发送大于1500字节的数据包时,您会发现它们会碎片化,甚至更糟。接收器将尽力将它拼凑在一起。 但如果遗漏了任何东西,那就再见了。实际上,限制实际上是在1500字节左右的标记处,但有时要小得多,以确保没有碎片并且它们到达。要发送大于该数据的数据,更高级别的协议必须将它们全部重新组合在一起,并请求丢失任何内容。

图像有多大?无论如何,64K可能太小了。

您有两个或三个选项。

1)使用TCP - 它可靠且面向流。您不必担心这会对您造成多大或多小或多碎片。

2)使用UDP但在顶部开发更高级别的应用程序协议。根据您的协议可能会有相当多的工作。我现在正在这样做。

3)看一下使用UDT库。它专为通过WAN传输批量数据而设计,性能优于TCP。

但是,我想建议TCP很可能适合您的需求。