Ошибка при записи большой строки в сокет? - PullRequest
0 голосов
/ 12 октября 2011

Привет всем моим друзьям,

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

На клиенте я отправляю файл,

BufferedWriter bufferedOut = null;
BufferedReader in = null;
socket = new Socket("192.168.0.15",4444);
bufferedOut = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

bufferedOut.write(xmlInString, 0, xmlInString.length());

/**
* wait for response
*/

byte[] buf = new byte[10000];
int actualNumberOfBytesRead = socket.getInputStream().read(buf);
String responseLine = new String(buf, 0, actualNumberOfBytesRead);

На сервере

 BufferedReader in = null;
 PrintWriter out = null;
 in = new BufferedReader(new InputStreamReader(client.getInputStream()));
 out = new PrintWriter(client.getOutputStream(), true);

//get the input
 byte[] buf = new byte[10000];
 int actualNumberOfBytesRead = client.getInputStream().read(buf);
 line = new String(buf, 0, actualNumberOfBytesRead);
 //send back
 out.println(result);

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

Спасибо всем

Ответы [ 2 ]

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

При использовании сокета TCP вы обрабатываете «потоки».То есть по умолчанию разделение между сообщениями отсутствует.Поступая так, как вы делаете, вы можете прочитать часть сообщения или, что еще хуже, прочитать больше, чем сообщение.

Самый распространенный способ - разделить ваши сообщения.Вы можете использовать DataInputStream / DataOutputStream, который кодирует строки в байты и использует первые байты, чтобы указать их длину.Таким образом, он знает, сколько байтов он должен прочитать на стороне получателя.

    DataOutputStream out = null;
    DataInputStream in = null;
    Socket socket = new Socket("192.168.0.15",4444);
    out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
    in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));

    out.writeUTF(xmlInString);
    out.flush(); // to ensure everything is sent and nothing is kept in the buffer.

    // wait for response

    String responseLine = in.readUTF();

Затем настройте соответствующий код сервера.

При использовании Buffered выходов с сокетами, чторекомендуется по соображениям производительности, рекомендуется flush() после того, как вы написали сообщение, чтобы убедиться, что все фактически отправлено по сети и ничего не хранится в буфере.

Ваша первоначальная проблема, вероятно, произошла, потому что ваше сообщение требуетнесколько пакетов TCP / IP, и на вашем сервере вы читаете только первый (ие), который только что прибыл.

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

Вам понадобится цикл для многократного чтения из входного потока, каждый раз объединяя прочитанные данные, пока не дойдете до конца строки.

Правка - немного подробнее. Если вы собираетесь передавать несколько таких строк / файлов, посмотрите ответ @ arnaud. Если все, что вам нужно, это отправить 1 большую строку, то:

  1. На стороне отправителя создайте выходной поток, отправьте данные (как вы это сделали), а затем не забудьте снова закрыть поток (это также выполнит сброс, который обеспечит отправку данных по проводу и сообщает другому концу, что больше нет данных).

  2. На сайте получателя считывайте данные в цикле, пока не закончится входной поток (read (buf) возвращает -1), объединяя данные каждый раз в один большой буфер, затем закройте входной поток.

Также, пожалуйста, прочитайте мой комментарий об отправке файла в байтах, а не в виде строки. Это особенно важно для файлов XML, которые имеют довольно специальные правила для обнаружения кодирования.

...