简体   繁体   English

套接字输入流在最终读取时挂起。 最好的处理方法?

[英]Socket input stream hangs on final read. Best way to handle this?

I'm a bit stumped on how to avoid my socket hanging on read.我对如何避免我的套接字挂起读取有点难过。 Here's my code:这是我的代码:

    Socket socket = new Socket("someMachine", 16003);
    OutputStream outputStream = socket.getOutputStream();
    InputStream inputStream = socket.getInputStream();
    try {
        outputStream.write(messageBuffer.toByteArray());
        outputStream.flush();
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
        StringBuffer response = new StringBuffer();
        int result;
        while ((result = in.read()) != -1) {
            response.append(Character.toChars(result));
            System.out.println(result);
        }
        System.out.println("Done!");  //never gets printed
     } catch (...) {}

The above code successfully reads all the data from the stream but then hangs.上面的代码成功地从流中读取了所有数据,但随后挂起。 Reading up on the net I was expecting to receive a -1 from the server (which I can't control) to indicate that I had reached the end of stream but instead I get this:在网上阅读我希望从服务器(我无法控制)收到 -1 以表明我已经到达流的末尾,但我得到了这个:

(Lots of data above this point)
57
10
37
37
69
79
70
10

It then hangs.然后挂起。 So, my questions are:所以,我的问题是:

1) Have I coded this wrong or is there an issue with the server's response? 1)我是否编码错误或服务器的响应有问题?

2) If there is an issue with the server's response (ie no -1 being returned), how can I work around this (ie to stop reading when it hangs). 2)如果服务器的响应有问题(即没有返回-1),我该如何解决这个问题(即当它挂起时停止读取)。

Any help appreciated!任何帮助表示赞赏!

The problem with just stopping where read would hang is that this can happen in 2 cases:仅仅在 read 挂起的地方停止的问题是这可能发生在 2 种情况下:

1: server doesn't have any more data to send 1:服务器没有更多数据要发送

2: The server has sent more data, but your client has not received it yet due to network overload. 2:服务器发送了更多的数据,但是由于网络过载,您的客户端还没有收到。

And you only want to really stop reading in the first case, but you want read to block in the second case.而且您只想在第一种情况下真正停止阅读,但您希望在第二种情况下阅读阻止。

The way to solve this is to make a transfer protocol(Standard) which allows the server to tell the client how much data it expects to send.解决这个问题的方法是制定一个传输协议(标准),它允许服务器告诉客户端它期望发送多少数据。

If the server knows the total data size in advance, simply start by sending the total number of bytes in the transfer, and then send the data.如果服务器事先知道总数据大小,只需从发送传输中的总字节数开始,然后发送数据。 That way the client knows when it have received all data.这样客户端就知道它何时收到了所有数据。

(Or the server can simply close the connection when done. That way read should fail, but this only work if you don't need the connection in the future) (或者服务器可以在完成后简单地关闭连接。这样read应该会失败,但这仅在您将来不需要连接时才有效)

I think you will only get -1 when the server decides to stop the conversation, ie closes its output stream or closes the socket completely.我想你只会在服务器决定停止对话时得到-1,即关闭它的输出流或完全关闭套接字。 Else, the stream stays open for potential future incoming data.否则,该流对未来可能的传入数据保持打开状态。

I'm not a Android expert, but this seems to work just fine on Android:我不是 Android 专家,但这似乎在 Android 上运行良好:

    try {
        telnetClient = new Socket(server, port);
    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    if (telnetClient.isConnected()) {
        try {
            InputStream instr = telnetClient.getInputStream();
            int buffSize = telnetClient.getReceiveBufferSize();
            if (buffSize > 0) {
                byte[] buff = new byte[buffSize];
                int ret_read = instr.read(buff);
                screen.append(new String(buff, 0, ret_read));
            }
        } catch (IOException e) {
            screen.append("Exception while reading socket:" + e.getMessage());
        }
    }

I've just had this exact same problem.我刚刚遇到了同样的问题。 I solved it by setting a timeout straight after creating the socket object... socket.setSoTimeout(10 * 1000);我通过在创建套接字对象后直接设置超时来解决它... socket.setSoTimeout(10 * 1000);

I found this problem to be pretty formidable.我发现这个问题非常棘手。 I was trying to execute a windows batch command from java and the process hangs every time trying to read the inputstream from the command getting executed.我试图从java执行一个windows批处理命令,每次尝试从执行的命令中读取输入流时,进程都会挂起。

I could only fix this inelegantly.我只能粗鲁地解决这个问题。

a) By looking for a specific line which I know would signal the end useful information form the stream. a)通过查找我知道的特定行,它将从流中发出最终有用信息的信号。
b) Or to start a new Thread that kills the process at the other end of the socket, in this case for me IEDriverServer.exe after a wait time. b)或者启动一个新的线程来杀死套接字另一端的进程,在这种情况下,对我来说是 IEDriverServer.exe 在等待时间之后。

String[] cmdArray = {"cmd.exe","/c",cmd+ " 2>&1" };
    InputStream is = new ProcessBuilder(cmdArray).directory(f).start().getInputStream();

        error_buffer = new BufferedReader(new InputStreamReader(is));
        int lines=0;

        while((line=error_buffer.readLine())!=null){
            if(line.startsWith("[INFO] Final Memory: ")) {
                break;
            }

            log.debug("Reading cmd Stream "+line);
            buf.append(line);
            lines++;
        }

尝试:

while ((result = in.read()) != null) {

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

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