【问题标题】:ICE4J DatagramPacket too smallICE4J DatagramPacket 太小
【发布时间】:2015-04-12 08:45:23
【问题描述】:

Regular DatagramSocket 工作正常...ICE4J DatagramSocket 似乎截断数据!?

发送大小的数据包是2500,但接收端总是1500(使用常规Java DatagramSocket,接收数据包大小与发送大小相同)。

接收结束:

 Component rtpComponent = stream.getComponent(org.ice4j.ice.Component.RTCP);
 CandidatePair rtpPair = rtpComponent.getSelectedPair();
 videoDS = rtpPair.getDatagramSocket();

在一个线程中:

byte[] buffer = new byte[250000000];
final DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
videoDS.receive(dp);
final byte[] clone = new byte[dp.getLength()];
System.arraycopy(dp.getData(), dp.getOffset(), clone, 0, dp.getLength());
final Image image = new Image(new ByteArrayInputStream(clone));

发送端几乎相同,只是它在 Android 上运行...

非工作代码之间的唯一区别在于第一段用于发送和接收。如果我使用普通的 Java Socket,它会工作(但当然不是在路由器后面,这就是我使用 Ice4J 的原因)。

【问题讨论】:

    标签: java android udp ice4j


    【解决方案1】:

    我发现了主要问题....

    参见 org.ice4j.stack.Connector 第 160 行

    /*
    * Make sure localSock's receiveBufferSize is taken into
    * account including after it gets changed.
    */
    int receiveBufferSize = 1500;
    

    数据显然被截断了......见第 188 行

    packet.setData(
                new byte[receiveBufferSize],
                0,
                receiveBufferSize);
    ....
    localSock.receive(packet); //line 200
    

    我当前的解决方案是将receiveBufferSize 编辑为25000,实际数据包数据是正确的数量。也许我会要求合并。

    【讨论】:

    • 错误是你的。您正在尝试发送一个不可行的大数据报,该数据报不受 (a) ICE4J (b) UDP (c) IP (d) 以太网或 PPPoE 或任何您的物理层的可靠支持。
    • 不要向 EJP 列出他不了解 Java 中的 UDP 协议.... 上述修复有效,并且已在 GitHub 中提交并获得批准。
    • 可悲的是,您正在使用 StackOverflow 为您的自尊心,不能承认我的回答是正确的。对库的修复,该库不必要地要求数据包符合 Java 规范 1500。如果它真的想强制执行,它应该对数据包进行分段(这当然是没有意义的,因为硬件级别的 Java 会这样做)......
    • 老实说,我无法想象有人会为自己的自尊投下正确的答案,这真是太可悲了......
    【解决方案2】:

    发送大小数据包为25,000,但接收端始终为1500

    永远不会接收到大于路径 MTU 的 UDP 数据报,除非:

    • 您和目标之间没有路由器,和/或
    • 数据报没有碎片化,或者
    • 所有碎片都到达了目标。

    否则任何片段的丢失都会导致整个数据报的丢失。

    普遍接受的 UDP 数据报有效负载限制为 534 字节。不是 25k。

    【讨论】:

    • 您没有抓住重点... 使用常规 Java 代码可以成功处理和传输所有信息。需要一些工作的是 ICE4J 代码。最后我添加了一个额外的零,我会解决这个问题。可悲的是,这不是问题。如果 ICE4J 有限制,应该可以更改 imo,但 1500 与 534 不匹配。
    • 是你没有抓住重点。其片段丢失的分段数据报永远不会被传递。 534 确保没有碎片。大于 1500 保证它。这是基本的 TCP/IP,与 Java 或特定软件无关。
    • 嗯...据我所知,数据报数据包被分段并一起编译并提供给 java 级别,或者它们被完全跳过......没有像只在 Java 中获取片段这样的事情@ 987654321@IMO 我通过使用 Java 进行传输证明了这一点,并表明 ICE4J 中存在特定的问题而不是网络限制。
    • 你刚刚同意我的看法。数据包要么原封不动地呈现给 Java,要么根本不呈现。因此,将责任归咎于 Java 之上的软件层就没有任何意义了。这一切都发生在 IP 和 UDP 层中。
    • 那么为什么我得到的数据包只有 1500?它们应该是完整的或根本不完整。你没有任何意义....
    猜你喜欢
    • 2011-08-11
    • 2015-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-25
    • 1970-01-01
    相关资源
    最近更新 更多