Как использовать BufferedWriter в сокетной коммуникации в Java? - PullRequest
0 голосов
/ 03 октября 2011

Я пытаюсь отправить строку через сокеты, но у меня просто есть некоторые проблемы. строка, которую я пытаюсь отправить, (ВНИМАНИЕ: Это строка, а не XML)

<message>
<header>
<messageType>snmp</messageType>
<sendFrom>192.168.0.16</sendFrom>
<hostName>oghmasysMehmet</hostName>
<sendTo>192.168.0.12</sendTo>
<receiverName>Mehmet</receiverName>
<date>03/10/2011</date>
</header>
<body>
<snmpType>getbulk</snmpType>
<ip>127.0.0.1</ip>
<port>161</port>
<oids>
  <oid>1.3.6.1.2.1.1.3.0</oid>
</oids>
<community>community</community>
<nR>0</nR>
<mR>5</mR>
</body>
</message>

Но когда я смотрю, что я получаю от сервера, это просто;

<?xml version="1.0" encoding="UTF-8"?>

Я не знаю, в чем проблема:

Я использую,

socket = new Socket(localIP, Integer.parseInt(localPort));
out = new PrintWriter(socket.getOutputStream(), true);

чтобы отправить строку с клиента и использовать,

in = new BufferedReader(new InputStreamReader(client.getInputStream()));
line = in.readLine();

для чтения строки на сервере.

Не могли бы вы помочь мне, как я могу решить это?

Спасибо всем

Ответы [ 5 ]

1 голос
/ 03 октября 2011

У Лукаса есть ответ, я полагаю. Лично я не доверяю readLine (), так как при этом делаю предположение, что вы получаете действительные данные String на сокете .... это очень плохое предположение!

Попробуйте сначала прочитать в байтовый буфер, а затем попытаться преобразовать его в строку:

byte[] buf = new byte[4096];

int actualNumberOfBytesRead = socket.getInputStream().read(buf);

String dataString = new String(buf, 0, actualNumberOfBytesRead);

... Теперь в моем примере есть несколько проблем, но необходимо сделать следующее замечание = D

1 голос
/ 03 октября 2011

Хорошо, вы написали какой-то XML, который содержит более одной строки.Первая строка:

<?xml version="1.0" encoding="UTF-8"?>

На сервере вы прочитали первую строку - вы получили один readLine() звонок.Неудивительно, что это дает вам одну строку текста.

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

Хорошийальтернатива не полагаться на строки вообще: префикс длины каждой отправляемой строки, поэтому вы отправляете:

  • Длина (в байтах) в виде 4 байтов
  • Строковые данные (в байтах)массив)

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

DataInputStream и DataOutputStream могут помочь вам сделать это достаточно просто.Обратите внимание, что вы обязательно должны указать кодировку, которую вы используете для всех строк;UTF-8 является хорошей отправной точкой в ​​большинстве случаев.

1 голос
/ 03 октября 2011

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

0 голосов
/ 03 октября 2011

Прежде всего: вы действительно должны использовать буфер для анализа того, что сервер отправил вам. См. http://www.kodejava.org/examples/266.html для хорошего примера.

Если вы ненавидите добавлять это в свой код, вы можете использовать библиотеку Apache Commons IO для следующих действий:

ByteArrayInputStream out = new ByteArrayInputStream();
IOUtils.readFully( in, out );
String output = new String( out.getBytes(), "UTF-8");

Обратите внимание, что вы должны позаботиться о сбрасывании () потока на стороне сервера. Позвольте клиенту закрыть сокет, как только все данные будут получены. Таким образом, вы не можете закрыть () сокет слишком рано.

0 голосов
/ 03 октября 2011

Я думаю, что вы должны зацикливаться на in.readline до тех пор, пока не будут доступны дополнительные данные.

Проверьте пример на http://download.oracle.com/javase/tutorial/networking/sockets/readingWriting.html

...