如何在 Java UDP 中获取实际数据包大小 `byte[]` 数组

Posted

技术标签:

【中文标题】如何在 Java UDP 中获取实际数据包大小 `byte[]` 数组【英文标题】:How to obtain the actual packet size `byte[]` array in Java UDP 【发布时间】:2014-03-19 02:28:03 【问题描述】:

这是我上一个问题的后续问题: Java UDP send - receive packet one by one

正如我在那里指出的,基本上,我想通过 UDP 一个接一个地接收数据包。

这是一个示例代码:

ds = new DatagramSocket(localPort);
byte[] buffer1 = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer1, buffer1.length);

ds.receive(packet); 
Log.d("UDP-receiver",  packet.getLength() 
                             + " bytes of the actual packet received");

这里,实际数据包大小是 300 字节,但 buffer1 分配为 1024 字节,对我来说,处理 buffer1 是有问题的。

如何从这里获取实际数据包大小byte[]数组?

而且,更根本的是,为什么我们需要像这样在 Java 中预先分配缓冲区大小来接收 UDP 数据包? (node.js 不这样做)

有没有办法不预先分配缓冲区大小,直接接收UDP数据包?

感谢您的想法。

【问题讨论】:

【参考方案1】:

您已经回答了自己的问题。 packet.getLength() 返回接收到的数据报中的实际字节数。所以,你只需要使用buffer[]从索引0到索引packet.getLength()-1.

请注意,这意味着如果您在循环中调用receive(),则必须在每次循环周围重新创建DatagramPacket,或者在接收之前将其长度重置为最大值。否则getLength() 会一直缩小到目前收到的最小数据报的大小。

【讨论】:

好的,谢谢 EJP,我在这里发布了我自己的答案。从我的日志来看,它似乎工作正常。【参考方案2】:

自我回答。我做了如下:

int len = 1024;
byte[] buffer2 = new byte[len];
DatagramPacket packet;

byte[] data;
while (isPlaying)

    try
    
        packet = new DatagramPacket(buffer2, len);
        ds.receive(packet);
        data = new byte[packet.getLength()];
        System.arraycopy(packet.getData(), packet.getOffset(), data, 0, packet.getLength());
        Log.d("UDPserver",  data.length + " bytes received");
    
    catch()//...........
//...........

【讨论】:

这毫无意义。您已经有一个包含数据的字节数组,并且您已经有了数据的长度,所以Log.d("UDPserver", packet.length() + " bytes received") 可以工作,就像您已经在问题中发布的代码一样。无需分配另一个数组并复制数据。

以上是关于如何在 Java UDP 中获取实际数据包大小 `byte[]` 数组的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Winsock 中查找当前使用的 UDP 接收缓冲区大小

如何发送具有确切大小的UDP数据包?

关于UDP的问题:包含多条消息和跨越的数据包

Python:如何处理大于最大 UDP 安全数据包大小的 UDP 数据包?

Java网络编程 - UDP通信

UDP IP 分片和 MTU