【问题标题】:java datagramchannel data lossjava datagramchannel 数据丢失
【发布时间】:2014-08-31 01:28:24
【问题描述】:

我读过一些关于 UDP/Java 数据报通道如何运作的相互矛盾的内容。我需要知道一些事情:

  • UDP 是否有一种继承方式来判断在调用 .read(ByteBuffer b) 之前接收到的数据包是否完整且有序?我至少读过一篇文章说 UDP 继承地丢弃不完整或乱序的数据。

  • datagramchannel 是否将一个发送(缓冲区..)视为一个数据报包?如果是部分发送呢?

  • 如果作为命令参数给出的缓冲区仅用于处理一个数据包,.read(..) 是否可以读取多个数据包,从而导致数据被丢弃?

【问题讨论】:

    标签: java networking network-programming udp datagram


    【解决方案1】:

    UDP 是否有一种 [固有] 方法来判断接收到的数据包是否完整且按顺序在 .read(ByteBuffer b) 被调用之前?我至少读过一篇文章说 UDP 继承丢弃不完整或乱序的数据。

    这两种说法都不正确。更准确地说,IP 有一种方法可以判断数据报的片段是否已全部到达,然后才将其呈现给 UDP。重组是 IP 层的责任,而不是 UDP。如果片段没有到达,UDP 甚至都看不到它。如果它们在重组完成之前过期,IP 会将它们丢弃。

    read() 被调用之前/之后是无关紧要的。

    datagramchannel 是否将一个send(buffer.. ) 视为一个数据报包?

    是的。

    如果是部分发送怎么办?

    UDP 中没有这样的东西。

    read(.. ) 能否读取多个数据包

    UDP 读取将准确返回一个数据报,否则失败。

    如果作为命令参数给出的缓冲区仅用于处理一个数据包,是否会导致数据被丢弃?

    不可能发生。

    您在下面的评论是关于一个完全不同的问题,检测截断的常用技术是使用比最大预期数据报大一个的缓冲区。然后,如果你得到一个这么大的数据报,(i)它是一个应用程序协议错误,并且(ii)它也可能被截断了。

    【讨论】:

    • “不可能发生。”我在 api 中引用了有关读取的这一行:如果数据报中的字节数多于给定缓冲区中的剩余字节数,则数据报的其余部分将被静默丢弃。有没有办法在读取之前告诉数据包的大小以避免这种情况?
    • @user1908813 不。通常的技术是使用比最大预期数据报大一号的缓冲区。那么,如果你得到一个这么大的数据报,(i)它是一个应用程序协议错误,并且(ii)它也可能被截断了。
    • 你也说IP是丢失数据包的原因,但是乱序的呢?
    • IP 没有“解释丢失的数据包”,我没有另外说。我说的是IP负责重组。如果一个片段乱序到达,IP 可能会也可能不会保留它,它是未定义的。
    猜你喜欢
    • 2015-04-18
    • 1970-01-01
    • 2014-11-01
    • 1970-01-01
    • 2015-01-28
    • 2017-02-16
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    相关资源
    最近更新 更多