가능한 해결책을 찾기 위해 여기를 포함하여 어디에서나 검색해 보았지만 성공하지 못했던 답변을 시도했습니다.Java 클라이언트에 소켓 응답 C 서버를 읽을 수 없습니다.
간단한 Java TCP 소켓 클라이언트를 구현했습니다. 클라이언트는 하나의 Java 서버에서 제대로 작동하지만 C로 코딩 된 서버로부터 응답을 수신하는 데 계속 문제가 있습니다. 서버가 트랜잭션을 올바르게 처리하고있는 것으로 보입니다. 따라서 응답을 적절하게 보냅니다. 문제는 클라이언트가 응답의 들어오는 스트림을 수신 할 수 있다는 것입니다. 이 내 초기 구현했다 : 나는 Wireshark를 다운로드하고 서버 소켓이 수신 대기중인 해당 포트에서 클라이언트와 서버 사이의 TCP 패킷 트래픽을 모니터링하는 데 사용
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);
. 비슷한 주제의 다른 스레드에서 여러 제안을 보았습니다. 불행히도 이러한 솔루션 중 하나를 얻을 수 없었습니다. 나는 회신을 포함하는 패킷이 플래그 값을 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 서버의 소스 코드에 액세스 할 수없는 있지만 개발자가 맹세 : 여기 바이트로하지만 아무 소용이 응답 바이트를 읽으려고 내가 스레드에서 발견이 구현 테스트를 시도 그 문제는 그의 목적이 아니며 나는 그를 믿는다. 또한 사용중인 다른 모든 클라이언트 아키텍처에서 작동하므로 변경을 할 수 없다는 것을 알고 있습니다. 코딩하는 것은이 C 기반 서버와 상호 작용하는 유일한 Java 클라이언트입니다. 구현에 오류가 있습니까? 아니면 응답 스트림을 더 바보 같은 방식으로 읽는 데 사용할 수있는 다른 구현이 있습니까?
다음은 클라이언트/서버 통신 프로세스를 실행하려고 노력의 결과입니다 :
[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
서버는 응답에 어떤 프로토콜을 사용합니까? 바이트 수준에서 문서화되어 있습니까? 서버가 기대하는 바를 모른다면 클라이언트가 올바른 일을하는지 여부를 어떻게 알 수 있습니까? (프로토콜 문서가 있습니까? 아니면 프로토콜을 리버스 엔지니어링해야합니까? 프로토콜 설명서가 있다면 공유하십시오. 프로토콜을 리버스 엔지니어링해야하는 경우 서버에서 보낸 바이트를 표시하여 도움을 줄 수 있습니다.) –