2015-01-17 5 views
0

Я пытаюсь отправить сообщения ISO8583, созданные с помощью библиотеки JPOS на Java. Что я сделал, написан простой код подключения сокета для отправки сообщения. Я могу отправить сообщение успешно, но проблема в том, что сервер отправляет ответ вовремя, но сообщение не читается моим клиентским сокетом. Он считывает данные только после того, как я принудительно закрою соединение (отключите сокет вручную) на сервере.Сообщение считывается только клиентом после закрытия сервера конца соединения в java

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

Вот мой пример кода для отправки:

logISOMsg(isoMsg); 
byte[] send_PackedRequestData = isoMsg.pack(); 
BufferedOutputStream outStream=null; 
BufferedReader receiveStream=null; 

Socket connection = new Socket("127.0.0.1", 5874); 
if (connection.isConnected()) { 

    outStream = new BufferedOutputStream(connection.getOutputStream()); 
    outStream.write(send_PackedRequestData); 
    outStream.flush(); 
} 

и для чтения:

if (connection.isConnected()) { 
    receiveStream = new BufferedReader(new InputStreamReader(connection.getInputStream())); 
    String isoMessage = receiveStream.readLine(); 

    ISOMsg isoMsg1 = new ISOMsg(); 
    isoMsg1.setPackager(packager); 

    byte[] bIsoMessage = new byte[isoMessage.length()]; 
    for (int i = 0; i < bIsoMessage.length; i++) { 
     bIsoMessage[i] = (byte) (int) isoMessage.charAt(i); 
    }         
    isoMsg1.unpack(bIsoMessage); 

    System.out.println("MTI='"+isoMsg1.getMTI()+"'");  
    for (int i=1; i<=isoMsg1.getMaxField(); i++) { 
     if (isoMsg1.hasField(i)) 
      System.out.println("DE : "+ i + " = " + isoMsg1.getString(i) + ""); 
    } 
} 
+0

Промыть буфер – MadProgrammer

+0

Какой буфер вы говорите о –

+0

Сервер может отправлять сообщение переменной длины, чтобы как можно решить клиент. –

ответ

2

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

На стороне отправителя вы просто отправляете сообщение без каких-либо дополнительных указаний о том, как приемник будет знать его длину. Поскольку я не знаю стандарта ISO8583, я не могу сказать, могут ли сообщения в этом формате иметь одну из вышеуказанных функций.

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

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

Кроме того, вы смешиваете строки и байтовые массивы, что является ошибкой здесь. Отправитель отправляет исходный массив байтов. Что происходит на стороне приемника, так это то, что InputStreamReader внутренне преобразует массив байтов в строку. Эта операция декодирует байты в символы с использованием кодировки, такой как UTF-8. Вы даже не указываете, какую кодировку использовать, поэтому вывод может быть довольно произвольным. После этого ваш код преобразует строку в массив байтов, но этот код неверен и не гарантирует восстановление исходного содержимого (результирующий массив байтов может отличаться от того, который был отправлен сервером).

Таким образом, вы не должны использовать класс Reader на стороне приемника, если вы не используете класс Writer на стороне отправителя. Вместо этого используйте только потоки, как и во время отправки.

 Смежные вопросы

  • Нет связанных вопросов^_^