Java丢弃一半的UDP数据包

Java丢弃一半的UDP数据包,java,c,networking,udp,datagram,Java,C,Networking,Udp,Datagram,我有一个简单的客户机/服务器设置。服务器是C语言,查询服务器的客户端是Java 我的问题是,当我通过连接发送带宽密集型数据(如视频帧)时,它最多会丢弃一半的数据包。我确保在服务器端正确地分割udp数据包(udp的最大有效负载长度为2^16)。我验证了服务器正在发送数据包(printf sendto()的结果)。但是java似乎没有得到一半的数据 此外,当我切换到TCP时,所有的视频帧都通过了,但是延迟开始增加,在运行几秒钟后增加了几秒钟的延迟 我有什么明显的遗漏吗?我似乎无法理解这一点。任何基于

我有一个简单的客户机/服务器设置。服务器是C语言,查询服务器的客户端是Java

我的问题是,当我通过连接发送带宽密集型数据(如视频帧)时,它最多会丢弃一半的数据包。我确保在服务器端正确地分割udp数据包(udp的最大有效负载长度为2^16)。我验证了服务器正在发送数据包(printf sendto()的结果)。但是java似乎没有得到一半的数据

此外,当我切换到TCP时,所有的视频帧都通过了,但是延迟开始增加,在运行几秒钟后增加了几秒钟的延迟


我有什么明显的遗漏吗?我似乎无法理解这一点。

任何基于UDP的应用程序协议都不可避免地会受到数据包丢失、重新排序和(在某些情况下)重复的影响。UDP中的“U”可以代表“不可靠”,就像在不可靠数据报协议中一样。(好的,它真的代表“用户”…但它确实是记住UDP特性的好方法。)

UDP数据包丢失通常是因为您的流量超过了服务器和客户端之间一个或多个“跃点”的缓冲容量。发生这种情况时,数据包将被丢弃。。。而且,由于您使用的是UDP,因此不会有传输协议级别的通知表明正在发生这种情况

如果在应用程序中使用UDP,应用程序需要考虑UDP的不可靠性质,实现自己的机制来处理丢弃和无序数据包,并进行自己的流控制。(如果一个应用程序在没有考虑到UDP数据包对已经过载的网络可能产生的影响的情况下抛出UDP数据包,那么它就是一个坏的网络公民。)

(在TCP情况下,数据包可能也被丢弃,但TCP正在检测并重新发送丢弃的数据包,TCP流控制机制正在启动以降低数据传输速率。最终结果是“延迟”。)

编辑-根据OP的评论,问题的原因是客户端有一段时间没有“监听”,导致数据包(可能)被客户端的操作系统丢弃。解决这一问题的方法是:

  • 使用一个专用的Java线程,只读取数据包并将其排队以进行处理,然后

  • 增加套接字的内核数据包队列的大小

  • 但即使你采取这些措施,你仍然可以得到数据包丢弃。例如,如果机器过载,应用程序可能无法频繁地获取执行时间片,无法在内核必须丢弃数据包之前读取所有数据包并将其排队

    编辑2-关于UDP是否容易重复存在一些争论。UDP确实没有天生的重复检测或预防功能。但是,作为互联网的IP数据包路由结构不太可能自动复制数据包,这也是事实。因此,如果发生重复,则很可能发生重复,因为发送方已决定重新发送UDP数据包。因此,在我看来,虽然UDP容易出现重复的问题,但它本身并不会导致这些问题。。。除非操作系统协议栈或IP结构中存在错误。

    获取一个类似的网络工具,这样您就可以看到线路上发生了什么


    UDP不进行重传尝试,因此如果数据包在某个地方丢失,则由程序处理丢失。TCP将努力按顺序将所有数据包交付给程序,丢弃DUP并自行请求丢失的数据包。如果您看到的是高延迟,我敢打赌您也会看到TCP的大量数据包丢失,这将显示为来自服务器的重新传输。如果看不到TCP重新传输,则可能是客户端处理数据的速度不够快,无法跟上。问题可能与UDPSocket中的传输缓冲区被填满有关。一次只发送
    UDPSocket.getSendBufferSize()
    指示的字节数。使用
    setSendBufferSize(int size)
    增加此值

    如果#send()用于发送 大于 SO_SNDBUF的设置则为 如果数据包 被发送或丢弃


    虽然UDP支持长度高达65535字节的数据包(包括8字节的UDP报头,但请参见注释1),但您和目标之间的底层传输不支持长度如此之长的IP数据包。例如,以太网帧的最大大小为1500字节——考虑到IP和UDP报头的开销,这意味着任何数据有效负载长度超过大约1450的UDP数据包都可能被分割成多个IP数据报

    一个最大大小的UDP数据包将被分割成至少45个独立的IP数据报——如果其中任何一个片段丢失,整个UDP数据包都将丢失。如果您的基本数据包丢失率为1%,您的应用程序将看到大约36%的丢失率

    如果您希望看到更少的数据包丢失,请不要发送大数据包-将每个数据包中的数据限制在1400字节左右(或者甚至执行您自己的“路径MTU发现”,以确定无碎片情况下可以安全发送的最大大小)


  • 当然,UDP也受到IP的限制,IP数据报的最大大小为65535,包括IP报头。IP报头的大小范围为20到60字节,因此UDP数据包中可传输的最大应用程序数据量可能低至65467

  • IP支持最多65535字节的数据包,包括20字节的IP数据包头UDP支持最多65507字节的数据报,加上20字节的IP报头和8字节的UDP报头。然而,网络MTU是实际的限制,不要忘记,它不仅包括这28个字节,还包括以太网