#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. У него есть методы для чтения целых чисел из байтов, а также метод для полного чтения массива указанного размера (для содержимого сообщения). Затем вы можете использовать новую строку (байт [], кодировка) для преобразования текстовой части (если это действительно текст, который можно представить в виде строки).