Java socket writeUTF() и readUTF()

Я читал фрагмент кода Java-сокета и выделял тот факт, что в сокетной связи, чтобы отправлять сообщения в последовательности, вам не нужно разделять их вручную, поток записи/чтения делает вещи автоматически для вы. Вот пример:

writer.java
writeUTF("Hello");
writeUTF("World");


reader.java
String a=readUTF(); // a=Hello
String a=readUTF(); // b=World

Я пробовал этот фрагмент кода, и он отлично работает. Тем не менее, мне интересно, должен ли этот тип кодирования работать нормально. Существуют ли потенциальные риски использования потока сокетов в последовательности без явного разделения каждого сегмента?

Ответ 1

writeUTF() и readUTF() записывают длину строки (в байтах, когда кодируются как UTF-8), за которой следуют данные, и используйте измененная кодировка UTF-8. Таким образом, есть некоторые потенциальные проблемы:

  • Максимальная длина строк, которые могут быть обработаны таким образом, составляет 65535 для чистого ASCII, меньше, если вы используете символы, отличные от ASCII, - и вы не можете легко предсказать предел в этом случае, за исключением консервативного предположения 3 байта на символ. Поэтому, если вы уверены, что никогда не будете отправлять строки дольше 20k, все будет в порядке.
  • Если приложение когда-либо нуждается в общении с чем-то другим (что не написано на Java), другой стороне может быть трудно обработать измененный UTF-8. Для внутренней связи с приложениями вам не нужно беспокоиться.

Ответ 2

В соответствии с документацией методы readUTF и writeUTF работают с модифицированной версией UTF8, которая также добавляет длину символа для чтения в начале.

Это должно означать, что операция чтения будет ждать до тех пор, пока не будет возвращено достаточное количество символов, прежде чем возвращать строку. Это означает, что они фактически сегментированы также, если вы не видите их, поскольку вы просто украшаете потоки сокета с помощью DataInputStream и DataOutputStream.

В заключение, да, это должно быть совершенно безопасно, поскольку сам API позаботится о разделении отдельных сообщений.

Ответ 3

java.net.Socket работает нормально, поток ждет readUTF();

Но при использовании mina CumulativeProtocolDecoder он не будет, бросает java.io.EOFException