当前位置: 首页 > 面试题库 >

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

易雅畅
2023-03-14
问题内容

我对如何避免套接字在读取时挂起有些困惑。这是我的代码:

    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:服务器已发送了更多数据,但由于网络过载,您的客户端尚未收到它。

在第一种情况下,您只想真正停止阅读,而在第二种情况下,您要阻止阅读。

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

如果服务器预先知道总数据大小,则只需先发送传输中的字节总数,然后再发送数据即可。这样,客户端便知道何时接收到所有数据。

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



 类似资料:
  • 问题内容: 简单的脚本在这里: a) 不断从套接字读取并将值存储在关联数组中 b) 不断从stdin读取值并响应t / f(如果它们已存在于关联数组中) a和b是随机事件,不以任何方式关联。 诀窍是从两个子流程访问数组(因为将流程放在后台会将其作为子流程生成) 我正在考虑最好的策略,并且出现了一些想法,但是我想知道是否有人有更好的想法: 1) 将输入从套接字重定向到stdin作为子进程,并在一个w

  • 与marshall和unmarshall的读者和作者有争议。就是这样。这就是我如何向版画作者写东西的方式。 我是这样得到它的: 然后此解组操作将挂起。它没有给我任何东西,甚至没有例外。

  • 我设法创建了基本的远程管理员工具,它运行良好,我使用了基本的tcp套接字和C++中的多线程。我可以用一些功能来远程使用它,这就像90%完成了,但我的软件没有任何东西可以检测客户端断开,除了当客户端手动关闭时,客户端会发送断开消息给服务器,但当用户拔掉网络插头或其他东西时,断开发生时,什么是最好的处理方法,我正在寻找一种专业的方法来做,比如如果客户端断开,服务器会立即检测到哪个客户端断开。

  • 问题内容: 我使用jQuery的$ .ajax()函数将大量数据发送给客户端。我正在ASP.NET Web服务中调用一个返回JSON数据的方法。对于大多数搜索而言,一切都很好,但是当我要返回大量数据集时,我遇到了JavaScriptSerializer MaxJsonLength属性问题。处理此问题的最佳做法是什么?我不想随意设置最大长度。如果返回的数据大于当前的最大值,是否可以在Web服务中设置

  • 用例: 每个用户都有一个项目列表。当在UI中创建一个新项目时,它会被添加到DynamoDB,然后再次获取整个列表,以显示新的结果。 问题是,在某些情况下,新添加的项不会出现在该列表中,这是基于索引(基于该用户ID的索引)的最终一致读取。 处理这种情况的正确方法是什么? “item”表将“itemId”作为索引的主分区键,“userId”作为索引的主分区键(在读取列表时查询)。

  • 我有java服务器和只有一个客户端的时间。 客户端连接并发送卡ID(在服务器端阻止读取是合适的,因为当时只有一个客户端)