【问题标题】:Infinite Loop in Input Stream输入流中的无限循环
【发布时间】:2012-09-27 14:41:46
【问题描述】:

我正在读取从套接字的服务器端接收的输入流。我无法知道我的响应的大小是多少,我正在读入一个字节数组,这是代码

public static String readString(InputStream inputStream) throws IOException {

    ByteArrayOutputStream into = new ByteArrayOutputStream();
    byte[] buf = new byte[4096];
    for (int n; 0 < (n = inputStream.read(buf));) {
        System.out.println("Got to this point n is "+n);
        into.write(buf, 0, n); 
    }
    into.close();
    System.out.println("passed this point");
    return new String(into.toByteArray(), AddATudeMessage.CHARENC); 
}

现在将数字 11 和 235 打印到控制台,因此我假设服务器仍在将输出写入输入流。然而,它卡在 235 并且似乎没有发生任何事情。我尝试暂停主执行线程长达 20 秒,此时我从服务器收到 241 个字节,然后再次发生相同的无限循环,任何人都知道发生了什么

【问题讨论】:

    标签: java sockets input inputstream


    【解决方案1】:

    您的代码的结构方式只有在服务器完成后关闭套接字时才能工作。否则,您的一方永远无法知道服务器是否已完成或仅仅是缓慢(或存在网络拥塞)。

    解决这个问题只有两种方法:

    1. 让服务器先发送预期长度,然后在收到指定字节数时停止读取并继续。
    2. 让服务器在完成后发送一个特殊的数据序列,一种在正常数据中不会出现的 EOF 标记,您可以在没有更多数据时找到它来告诉您。

    使用available() 的解决方案不正确,因为如果接收缓冲区当前为空但仍有数据在传输中,它会返回零。

    【讨论】:

    • @crazycasta 服务器没有关闭套接字,我必须检查是否有行尾字符,然后我停止阅读
    【解决方案2】:

    方法 int InputStream.read() 阻塞,直到它从套接字接收数据,接收到流序列的结尾或抛出异常。

    考虑使用这个语句:

       for (; inputStream.available() > 0;)
    

    在这种情况下,如果套接字上没有可用数据,则 for 循环结束,您的程序可以继续。当然,你必须调整你的代码来做你想做的事情。

    【讨论】:

      【解决方案3】:

      考虑使用int available() (InputStream)
      它返回可以从此输入流读取(或跳过)的字节数,而不会被该输入流的方法的下一个调用者阻塞。

      【讨论】:

        【解决方案4】:

        inputStream.read(buf) 不会返回 0,直到服务器关闭套接字(或者可能是元数据包的一些特殊情况或其他东西)。

        【讨论】:

          猜你喜欢
          • 2012-03-12
          • 2012-10-18
          • 2021-03-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-09
          • 1970-01-01
          相关资源
          最近更新 更多