【问题标题】:Why does setting SO_TIMEOUT cause final read of SocketInputStream to return immediately?为什么设置 SO_TIMEOUT 会导致 SocketInputStream 的最终读取立即返回?
【发布时间】:2013-07-31 04:37:55
【问题描述】:

我正在开发一个测试工具,该工具通过套接字将字节写入服务器并读取响应。我遇到了一个问题,即最后一次读取 Socket 的 InputStream 会暂停 20 秒。我解决了这个问题,但不明白为什么会这样。

下面的方法给出了一个 java.net.SocketInputStream。对 read(byte[], int, int) 的调用在最后一次读取时暂停了 20 秒,返回 -1 表示流结束。

    private String getResponse(InputStream in) throws IOException {

    StringBuffer buffer = new StringBuffer();
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    byte[] data = new byte[1024];
    int bytesRead = 0;
    while (bytesRead >= 0) {
        bytesRead = in.read(data, 0, 1024);    // PAUSED HERE ON LAST READ
        if (bytesRead > 0) {
            bout.write(data, 0, bytesRead);
        }
        buffer.append(new String(data));
    }
    return buffer.toString();
}

我可以通过在套接字上设置 SO_TIMEOUT 来消除暂停。我设置它似乎并不重要。即使使用 socket.setSoTimeout(60000),在上述方法中读取的问题也会在流结束时立即返回。

这里发生了什么?为什么设置 SO_TIMEOUT,即使设置为高值,也会导致对 SocketInputStream 的最终读取立即返回?

【问题讨论】:

  • SO_TIMEOUT 没有这种效果。这里真正的问题是为什么要暂停?这只能由发送方发送最终数据的速度慢来解释。

标签: java sockets java-io


【解决方案1】:

这听起来难以置信。设置套接字超时不应该有这种效果。

我认为最可能的解释是您更改了其他内容,而 那个 是修复了暂停的原因。 (如果我猜的话,服务器现在正在关闭它之前没有这样做的套接字。)

如果这没有帮助,您需要提供一个 SSCCE,其他人可以运行以观察效果。并告诉我们您使用的是什么平台。

【讨论】:

  • 打算在几个月前回复这个。你确实是对的。服务器更改为关闭套接字,这就是为什么最终的 InputStream.read 开始立即返回,正如预期的那样。谢谢。
猜你喜欢
  • 2011-01-14
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-19
  • 2016-07-13
  • 2011-11-02
  • 1970-01-01
相关资源
最近更新 更多