Why can I reuse DatagramPacket without resetting the length

This appeared when answering BufferedWriter only works for the first time

As far as I understand the Java Doc (and this is confirmed by many posts on the network), DatagramPacket should not accept more data than the current size. The documentation for DatagramSocket.receive states

This method is blocked until a datagram is received. The length field of the packet data object contains the length of the received message. If the message is longer than the packet length, the message is truncated.

So, I created a program that reuses the receiving packet and sends it longer and longer messages.

public class ReusePacket { private static class Sender implements Runnable { public void run() { try { DatagramSocket clientSocket = new DatagramSocket(); byte[] buffer = "1234567890abcdefghijklmnopqrstuvwxyz".getBytes("US-ASCII"); InetAddress address = InetAddress.getByName("127.0.0.1"); for (int i = 1; i < buffer.length; i++) { DatagramPacket mypacket = new DatagramPacket(buffer, i, address, 40000); clientSocket.send(mypacket); Thread.sleep(200); } System.exit(0); } catch (Exception e) { e.printStackTrace(); } } } public static void main(String args[]) throws Exception { DatagramSocket serverSock = new DatagramSocket(40000); byte[] buffer = new byte[100]; DatagramPacket recievedPacket = new DatagramPacket(buffer, buffer.length); new Thread(new Sender()).start(); while (true) { serverSock.receive(recievedPacket); String byteToString = new String(recievedPacket.getData(), 0, recievedPacket.getLength(), "US-ASCII"); System.err.println("Length " + recievedPacket.getLength() + " data " + byteToString); } } } 

Output signal

 Length 1 data 1 Length 2 data 12 Length 3 data 123 Length 4 data 1234 Length 5 data 12345 Length 6 data 123456 ... 

So, even if the length is 1, for the next receipt, it receives a message of length 2 and does not truncate it. However, if I manually set the packet length, then the message will be truncated to this length.

I tested this on OSX 10.7.2 (Java 1.6.0_29) and Solaris 10 (Java 1.6.0_21). So to my questions.

Why does my code work and can expect it to work with other systems?

To clarify, the behavior seems to have changed once (at least for some JVMs), but I don't know if the old behavior was a mistake. I am fortunate that it works this way and I should expect it to work the same in Oracle JVM, IBM JVM, JRockit, Android, AIX, etc.

After further study and verification of the source 1.3.0, 1.3.1, and 1.4.0, a change was introduced in the Sun implementation from 1.4.0, but this is not mentioned in the release notes or on the network for specific release notes for JDK 1.4.0 .

+7
source share
1 answer

There are two different lengths. The length of the packet in the constructor is 100:

 DatagramPacket recievedPacket = new DatagramPacket(buffer, buffer.length); 

According to the docs, the length() method tells you the length of the message that is currently stored in the package, what it does. Change

 byte[] buffer = new byte[100]; 

to

 byte[] buffer = new byte[10]; 

outputs the following result:

 Length 1 data 1 Length 2 data 12 ... Length 9 data 123456789 Length 10 data 1234567890 Length 10 data 1234567890 Length 10 data 1234567890 ... 
+6
source

All Articles