简体   繁体   English

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

[英]Unable to read socket response C server to Java client

I've searched everywhere including here for possible solutions and tried some of the answers I found with no success.我到处搜索,包括这里寻找可能的解决方案,并尝试了我找到的一些没有成功的答案。

I implemented a simple Java tcp socket client.我实现了一个简单的 Java tcp 套接字客户端。 The client works really well with one Java server but I keep having problems receiving the response from a server coded in C. The server appears to be handling the transaction correctly and it sends a reply accordingly.客户端在一台 Java 服务器上工作得非常好,但我一直在从用 C 编码的服务器接收响应时遇到问题。服务器似乎正确处理事务并相应地发送回复。 The problem lies in the client being able to receive the incoming stream of the reply.问题在于客户端能够接收回复的传入流。 This was my initial implementation:这是我最初的实现:

        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);

I downloaded Wireshark and used it to monitor the tcp packet traffic between the client and server in the corresponding port the server socket is listening on.我下载了 Wireshark 并使用它来监视服务器套接字正在侦听的相应端口中客户端和服务器之间的 tcp 数据包流量。 I saw multiple suggestions in other threads with similar topics, I unfortunately was not able to get any of those solutions to work for me.我在具有类似主题的其他线程中看到了多个建议,不幸的是,我无法让这些解决方案中的任何一个对我有用。 I found that the packet containing the reply has the flag value set to PSH (for do not buffer steam upon receiving, process immediately).我发现包含回复的数据包的标志值设置为 PSH(因为在接收时不缓冲蒸汽,立即处理)。 I thought that the Java client by attempting to buffer the reply was causing the connection to reset (RST that appears in the failure packet, which is the next one that occurs) because of this flag.我认为 Java 客户端通过尝试缓冲回复导致连接重置(出现在失败数据包中的 RST,这是下一个发生的),因为这个标志。 I tried testing with this implementation I found in a thread here trying to read the reply byte by byte but to no avail:我尝试使用这个实现进行测试,我在一个线程中找到了一个试图逐字节读取回复但无济于事的线程:

  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();
        }

I do not have access to the source code for the C server but its developer swears to me that the problem is not on his end and I believe him.我无权访问 C 服务器的源代码,但它的开发人员向我发誓,问题不在他的一端,我相信他。 I also know he can't make changes to it as it works with every other client architecture in use, the one I'm coding happens to be the only Java client one that interacts with this C based server.我也知道他无法对其进行更改,因为它适用于正在使用的所有其他客户端架构,我正在编写的代码恰好是唯一一个与这个基于 C 的服务器交互的 Java 客户端。 Is there an error in my implementation or is there another implementation I could use to read the reply stream in a more fool-proof way?我的实现中是否存在错误,或者是否有其他实现可以用来以更简单的方式读取回复流?

Here's the results of trying to run the client/server comm process:以下是尝试运行客户端/服务器通信进程的结果:

[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)

The RST doesn't have anything to do with the PSH or the buffered reader, but if you need to read binary the reader isn't appropriate. RST 与 PSH 或缓冲读取器没有任何关系,但如果您需要读取二进制文件,则读取器不合适。 The RST indicates that the peer closed the connection before you read from it, which is a strong indication that you're using the wrong protocol. RST 表明对等方在您读取之前关闭了连接,这强烈表明您使用了错误的协议。 It isn't credible that the request protocol is line-based but the response protocol is length-word-prefix-based.请求协议是基于行的,但响应协议是基于长度字前缀的,这是不可信的。 One or the other, or something else.一个或另一个,或别的什么。

If you determine that it really is a length-word-prefix protocol, try this:如果您确定它确实是一个长度字前缀协议,请尝试以下操作:

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

But you need confirmation of the actual protocol.但是您需要确认实际协议。 Guesswork won't get you there.猜测不会让你到达那里。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM