Я искал всюду, в том числе здесь, для возможных решений и пробовал некоторые из ответов, которые я нашел без успеха.Невозможно прочитать ответ сокета C-сервер на Java-клиент
Я реализовал простой клиент Java tcp socket. Клиент отлично работает с одним сервером Java, но у меня возникают проблемы с получением ответа от сервера, закодированного в C. . Сервер, похоже, правильно обрабатывает транзакцию и отправляет ответ соответствующим образом. Проблема заключается в том, что клиент может получать входящий поток ответа. Это была моя первая реализация:
String msg_out = message;
String reply;
//the stream object to transmit message to server
DataOutputStream outStream = new DataOutputStream(clientSocket.getOutputStream());
outStream.writeBytes(msg_out + '\n');
outStream.flush();
//try to break away from locked read
//clientSocket.setSoTimeout(10000);
//initial implementation
//the object to receive reply server
BufferedReader replyStream = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
reply = replyStream.readLine();
System.out.println("Reply from "+ host + ":" + port + " -> " + reply);
Я скачал Wireshark и использовал его для мониторинга трафика TCP пакетов между клиентом и сервером в соответствующем порту сокет сервера прослушивает. Я видел несколько предложений в других потоках с похожими темами, я, к сожалению, не смог заставить ни одно из этих решений работать для меня. Я обнаружил, что пакет, содержащий ответ, имеет значение флага, установленное в PSH (для того, чтобы не загружать пар при получении, немедленно обработать). Я думал, что клиент Java, пытаясь буферизовать ответ, вызвал перезагрузку соединения (RST, который появляется в пакете отказа, который является следующим, который возникает) из-за этого флага. Я попытался тестирование с помощью этой реализации я нашел в потоке здесь, пытаясь прочитать ответ побайтно, но не дали никаких результатов:
try {
DataInputStream in = new DataInputStream(clientSocket.getInputStream());
int bytesRead = 0;
byte[] messageByte = new byte[1000];
boolean end = false;
String messageString = "";
messageByte[0] = in.readByte();
messageByte[1] = in.readByte();
ByteBuffer byteBuffer = ByteBuffer.wrap(messageByte, 0, 2);
int bytesToRead = byteBuffer.getShort();
System.out.println("About to read " + bytesToRead + " octets");
//The following code shows in detail how to read from a TCP socket
while(!end)
{
bytesRead = in.read(messageByte);
messageString += new String(messageByte, 0, bytesRead);
if (messageString.length() == bytesToRead)
{
end = true;
}
}
System.out.println("Server Reply: " + messageString);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
у меня нет доступа к исходному коду для сервера C, но его разработчик клянется что проблема не в его конце, и я ему верю. Я также знаю, что он не может вносить в него изменения, поскольку он работает с любой другой используемой архитектурой клиента, тот, который я кодирую, является единственным Java-клиентом, который взаимодействует с этим сервером на основе C. Есть ли ошибка в моей реализации или есть ли другая реализация, которую я мог бы использовать, чтобы читать поток ответов более надежным способом?
Вот результаты пытаются запустить процесс комм клиента/сервера:
[2/10/17 14:23:49:658 EST] 00000031 SystemOut O Outgoing transaction message:C00052!GDT43000KU!01!D-10!G-11!NORMAL!|
[2/10/17 14:23:49:658 EST] 0000011e SystemOut O Buffersize in stream:8192
[2/10/17 14:23:49:737 EST] 0000011e SystemOut O About to read 12336 octets
[2/10/17 14:23:49:737 EST] 0000011e SystemErr R java.net.SocketException: Connection reset
[2/10/17 14:23:49:737 EST] 0000011e SystemErr R at java.lang.Throwable.<init>(Throwable.java:67)
[2/10/17 14:23:49:737 EST] 0000011e SystemErr R at java.net.SocketInputStream.read(SocketInputStream.java:118)
[2/10/17 14:23:49:737 EST] 0000011e SystemErr R at java.io.DataInputStream.read(DataInputStream.java:94)
[2/10/17 14:23:49:737 EST] 0000011e SystemErr R at com.gf.btv.RTDLTSS.domain.LTSSClient.TCPClientRequest(LTSSClient.java:141)
[2/10/17 14:23:49:737 EST] 0000011e SystemErr R at com.gf.btv.RTDLTSS.helper.LTSSClientThread.run(LTSSClientThread.java:147)
[2/10/17 14:23:49:737 EST] 0000011e SystemErr R at java.lang.Thread.run(Thread.java:736)
Вы уверены, что отправлены в Big Endian? Некоторые программы на C предполагают, что они малочисленны, –
* Что на самом деле происходит * при попытке запустить клиент? – immibis
Какой протокол используется сервером для ответа? Документировано ли это на уровне байтов? Как вы можете узнать, делает ли ваш клиент правильные вещи, если вы не знаете, что ожидает от него сервер? (У вас есть протокольная документация? Или вам нужно перепроектировать протокол? Если у вас есть протокольная документация, поделитесь им. Если вам нужно перепроектировать протокол, покажите нам байты, которые сервер отправил вам, чтобы мы могли помочь вам сделайте это.) –