套接字输入流在最终读取时挂起。处理这个问题的最佳方法是什么?

2022-09-04 01:00:07

我有点难过如何避免我的插座挂在阅读上。这是我的代码:

    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 (...) {}

上面的代码成功从流中读取所有数据,但随后挂起。在网上阅读,我期望从服务器收到一个-1(我无法控制),以表明我已经到达了流的末尾,但我得到了这个:

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

然后它会挂起。所以,我的问题是:

1)我是否编码错误,或者服务器的响应是否存在问题?

2)如果服务器的响应有问题(即没有返回-1),我该如何解决这个问题(即在挂起时停止读取)。

任何帮助赞赏!


答案 1

仅仅停止读取挂起的位置的问题在于,这可能在2种情况下发生:

1:服务器没有更多的数据要发送

2:服务器已发送更多数据,但由于网络过载,您的客户端尚未收到。

你只想在第一种情况下真正停止阅读,但你想在第二种情况下阻止阅读。

解决这个问题的方法是制定一个传输协议(标准),允许服务器告诉客户端它期望发送多少数据。

如果服务器事先知道总数据大小,只需从发送传输中的总字节数开始,然后发送数据即可。这样,客户端就可以知道何时接收了所有数据。

(或者服务器可以在完成后简单地关闭连接。这种方式应该会失败,但这只有在您将来不需要连接时才有效)read


答案 2

我认为只有当服务器决定停止对话时,即关闭其输出流或完全关闭套接字时,您才会得到-1。否则,流将保持打开状态,以便将来可能传入数据。


推荐