Отправка строки с Java-клиента на сервер NodeJS через сокет также отправляет нежелательные символы

#java #node.js #sockets

#java #node.js #сокеты

Вопрос:

Я хочу отправить массив строк с моего Java-клиента на мой сервер NodeJS с помощью сокетов. Мои намерения сложнее, но я думаю, что все можно свести к следующим строкам кода:

Java

 Socket s = new Socket("localhost", 6666);
DataOutputStream dout = new DataOutputStream(s.getOutputStream());
dout.writeUTF("test");  // also tried writeChars and writeBytes
  

NodeJS

 require('net').createServer(function (socket) {

    console.log("connected");

    socket.on('data', function (data) {
        console.log(data.toString())
    });

}).listen(6666);
  

Просто запуская сервер, затем клиент, я получаю:

введите описание изображения здесь

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

Комментарии:

1. Можете ли вы использовать netcat , чтобы проверить, есть ли проблема? Используйте nc localhost 6666 и протестируйте NodeJS сервер сокетов. Используйте nc -l -p 6666 для тестирования Java-клиента (без NodeJS)

Ответ №1:

Используйте OutputStreamWriter вместо DataOutputStream:

 Socket s = new Socket("localhost", 6666);
OutputStreamWriter out = new OutputStreamWriter(s.getOutputStream(), StandardCharsets.UTF_8);
out.write("test");
out.flush();
  

DataOutputStream предназначен для использования с DataInputStream классом Java, и форматы обмена данными, которые они используют, несколько нестандартны. Это особенно относится к writeUTF методу: Он начинается с записи длины строки в виде 2-байтового двоичного числа. Затем он записывает символы строки, используя нестандартную кодировку символов.

Если вы обмениваетесь информацией с программным обеспечением, не написанным на Java, проще просто не использовать классы DataOutput / InputStream.

Ответ №2:

По моему опыту, самый безопасный способ отправить строку через сокет — это отправить ее массив байтов следующим образом:

 public static void main(String[] args) {
    try (Socket s = new Socket("localhost", 6666)) {
        DataOutputStream dout = new DataOutputStream(s.getOutputStream());
        dout.writeUTF("test utf");
        dout.writeUTF("hello from ☕");
        dout.writeUTF("n");
        dout.write("test byte[]".getBytes());
        dout.write("hello from ☕".getBytes());
        dout.write("I support unicode ✁ ✂ ✃ ✄ ✆".getBytes());
    } catch (IOException ioe) {
        // do nothing
    }
}
  

Но даже путем репликации вашего кода я не смог воспроизвести неизвестный символ:

 ~/Projects/scratch via ⬢ v12.18.3 
➜ node server.js
connected
test utfhello from ☕
test byte[]hello fromI support unicode ✁ ✂ ✃ ✄ ✆
  

вывод терминала