Как я могу убедиться, что мой сервер читает то, что написал клиент?

#java #sockets #objectoutputstream

#java #сокеты #objectoutputstream

Вопрос:

Я записываю массив байтов из клиента сокета как:

 byte[] arr = { 49, 49, 49, 49, 49};

InetAddress address = InetAddress.getByName(host);
connection = new Socket(address, port);
out = new ObjectOutputStream(connection.getOutputStream());
out.flush();
  

На принимающей стороне на сервере у меня есть:

 byte[] msgType = new byte[5];
in = new BufferedInputStream(connection.getInputStream());
int bytesRead = in.read(msgType, 0, 5);

System.out.println("msg rcvd: "   msgType.toString());
  

На выходе я получаю странную строку:

 server: waiting for connection
server: connection received from localhost
server: Connection Successful
bytes read: 5
msg rcvd: ��w
  

Как убедиться, что я получаю те же байты, что и отправленные от моего клиента?

Ответ №1:

Я не уверен точно, что именно пытаются распечатать, но я могу сказать вам, что msgType.toString() содержимое массива байтов не будет напечатано.

Вот найденная мной ссылка на метод, который будет выводить массив байтов более осмысленным образом.

Ответ №2:

Вы получаете одни и те же байты, это просто вопрос того, как вы их интерпретируете. Если вы хотите видеть байты как String используйте это вместо:

 System.out.println("msg rcvd: "   new String(msgType, "UTF-8"));
  

Будьте осторожны, чтобы байты, с которыми вы имеете дело, имели правильную кодировку (здесь я предположил UTF-8). Поскольку вы уже ObjectOutputStream используете его, вы могли бы просто использовать его writeUTF() на стороне сервера и ObjectInputStream.readUTF() на стороне клиента.

Ответ №3:

Если вы используете ObjectOutputStream на одной стороне, вам придется использовать ObjectInputStream на другой стороне.

В вашем случае подойдет простой OutputStream (возможно, буферизованный) и .write() и .read() .

Но для печати не используйте byte[].toString() , используйте Arrays.toString() , если хотите получить форматированный вывод.


Редактировать: я просто вижу, что вы даже не записываете свой массив на стороне отправки. Таким образом, вы на самом деле читаете только заголовок ObjectOutputStream.


Из комментария:

Я обрабатываю серверную часть, и мне говорят, что я отправлю массив байтов. Как мне получить и распечатать этот массив байтов? массив байтов в данном случае — это байты текста / строк

Похоже, что сервер отправляет что-то вроде простых строк, закодированных в некоторой кодировке, такой как ASCII, UTF-8 или ISO-8859-1. Если да, то на принимающей стороне вы можете использовать что-то вроде этого:

 String encoding = "UTF-8";
BufferedReader in =
    new BufferedReader(new InputStreamReader(connection.getInputStream(),
                                             encoding));
String line;
while((line = in.readLine()) != null) {
    System.out.println(line);
}
  

Конечно, убедитесь, что кодировка совпадает с той, которая фактически используется на стороне отправки.

Соответствующий код отправки может быть примерно таким:

 String encoding = "UTF-8";
Writer w =
    new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(),
                                              encoding));
w.write("Hello World!n");
w.write("And another line.n");
w.flush();
  

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

1. согласен, если вы используете ObjectOutputStream или ObjectInputStream, вы должны использовать оба. В этом случае вам не нужно ни то, ни другое.

2. @meBigFatGuy — как я могу убедиться, что клиентская сторона использует тот же поток, что и серверная. Я обрабатываю серверную часть, и мне говорят, что я отправлю массив байтов. Как мне получить и распечатать этот массив байтов? массив байтов в данном случае — это байты текста / строк.

3. @Paulo — Спасибо! Я думаю, мне нужно рассказать вам мой точный вариант использования, поскольку я думаю, что вы могли бы помочь мне понять, как с этим справиться. Моя структура сообщений выглядит примерно так: 1 байт — код сообщения, 2-5 байт — длина сообщения, за которой следует содержимое сообщения. Содержимое сообщения представляет собой двоичный текст, который я также планирую обрабатывать так, как вы отправили, но код и длина являются целыми числами. Также полное сообщение отправляется в виде byte[] . итак, как я могу получить первый байт, затем следующие 4 байта, а затем байт [] двоичного текста.

4. Если у вас есть указанный двоичный протокол, используйте DataInputStream /DataOutputStream (вместо Reader / Writer) для реализации его со стороны Java. У него есть методы для чтения целых чисел из байтов, а также метод для полного чтения массива указанного размера (для содержимого сообщения). Затем вы можете использовать новую строку (байт [], кодировка) для преобразования текстовой части (если это действительно текст, который можно представить в виде строки).