无法读取套接字响应C服务器到Java客户端

问题描述:

我到处搜索包括这里寻找可能的解决方案,并尝试了一些我发现没有成功的答案。无法读取套接字响应C服务器到Java客户端

我实现了一个简单的Java tcp套接字客户端。客户端在一台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服务器,但它的开发者发誓要我认为问题不在他的最后,我相信他。我也知道他不能对它进行更改,因为它可以与所有其他正在使用的客户端架构一起使用,我编码的那个恰好是与此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) 
+0

你确定他们发送Big Endian吗?一些C程序假设小端, –

+1

*当您尝试运行客户端时实际发生了什么? – immibis

+1

服务器使用什么协议来回复?它是否在字节级记录?如果你不知道服务器期望它做什么,你怎么可能知道你的客户是否做对了? (你有协议文档吗?或者你需要对协议进行反向工程?如果你有协议文档,分享它。如果你需要对协议进行逆向工程,请告诉我们服务器发送给你的字节,这样我们可以尝试帮助你) –

的RST没有什么关系的PSH或缓冲的读者,但如果你需要阅读二进制读者不合适。 RST表示对方在您读取连接之前关闭了连接,这表明您正在使用错误的协议。请求协议是基于行的,但响应协议是基于长度字前缀的,这是不可信的。一个或另一个,或别的东西。

如果确定它确实是一个长字前缀协议,试试这个:

int messageLength = in.readShort(); 
byte messageBytes = new byte[messageLength]; 
in.readFully(messageBytes); 
// etc. 

但你需要实际的协议的确认。猜测不会让你在那里。

+0

我会再次问一次,以确保我们知道这种情况,但我真的不认为这个问题与此有关。 – rocklandcitizen

+0

你应该再次询问以确保你知道*协议。*你已经在这里使用了两个,并且这两个都是正确的。很可能*既不*也是正确的。 – EJP

+0

我注意到假设'短'(2字节int)值是12336,这是两个字节的值,每个字节包含ASCII字符'0'。我怀疑服务器实际上是以字符形式发送长度或其他值。 –