Почему я могу повторно использовать DatagramPacket без сброса длины

Это возникло при ответе BufferedWriter работает только в первый раз

Насколько я понимаю Java Док (и это подтверждается многими сообщениями в сети) DatagramPacket не должен принимать больше данных, чем его текущий размер. В документации к DatagramSocket.receive сказано

: этот метод блокируется до тех пор, пока не будет получена дейтаграмма. Поле длины объекта пакета дейтаграммы содержит длину полученного сообщения.Если сообщение длиннее, чем длина пакета, сообщение обрезается.

Итак, я создал программу, которая повторно использует получаемый пакет и отправляет ему все более длинные сообщения.

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);
        }
    }
}

Результатом будет

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

Таким образом, даже если длина равна 1, в следующем приеме он получит сообщение длиной 2 и не будет его усекать. Однако, если я вручную установлю длину пакета, сообщение будет обрезано до этой длины.

Я тестировал это на OSX 10.7.2 (Java 1.6.0_29) и Solaris 10 (Java 1.6.0_21). Итак, на мои вопросы.

Почему мой код работает и можно ожидать, что он будет работать и в других системах?

Чтобы уточнить, поведение, похоже, когда-то в прошлом изменилось (по крайней мере, для некоторых JVM), но я не знаю, старое поведение было ошибкой. Мне повезло, что он работает таким образом, и следует ли ожидать, что он будет работать таким же образом на Oracle JVM, IBM JVM, JRockit, Android, AIX и т. Д.?

После дальнейшего исследования и проверки исходного кода на версии 1.3.0, 1.3.1 и 1.4.0 изменение было внесено в реализацию Sun начиная с версии 1.4.0, однако об этом не упоминается ни в примечаниях к выпуску, ни в примечаниях к выпуску JDK 1.4.0 для конкретной сети.

8
задан Community 23 May 2017 в 11:54
поделиться