【问题标题】:Java DataInputStream read does not returnJava DataInputStream 读取不返回
【发布时间】:2019-02-19 17:13:44
【问题描述】:

我正在实现一个简单的客户端/服务器读取器,我正在使用 DataInputStream 将所有内容读取为字节,然后再进行解析。

这是我的阅读代码:

String line;
String requestString = "";

//client is a Socket that is initialized elsewhere
DataInputStream inputData = new DataInputStream(client.getInputStream());
byte [] messageByte = new byte[1024];
int counter = 0;
  while(true) {  
    int bytesRead = inputData.read(messageByte, counter, 1024-counter);
    counter = (counter + bytesRead)%1024;
    if(bytesRead == -1) {
      System.out.println("Breaking out of loop");
      break;
    }
    line = new String(messageByte, 0, bytesRead);
    System.out.println( "GOT > " + line );
  }

它可以读取消息,但不能跳出循环,因为最后一次调用 read 没有返回。

【问题讨论】:

  • 只有当您到达流的末尾时,您才会因为read 调用而得到-1。在套接字的情况下,这意味着另一端必须关闭连接。
  • counter 的目的是什么?似乎它没有任何用途,并且使您的代码更难理解。你可以用int bytesRead = inputData.read(messageByte, 0, messageByte.length);替换int bytesRead = inputData.read(messageByte, counter, 1024-counter);
  • 你可以使用available()吗?
  • @Progman available 不是一个好的选择,网络上有延迟。现在没有可用的输入,并不意味着以后不会有。
  • @AlexandarPetrov 那么当你期望它不会阻塞时,这个调用阻塞的问题是什么?

标签: java sockets inputstream blocking


【解决方案1】:

套接字将阻塞,直到没有更多输入。 InputStream 只是一个接口,具体行为取决于它的提供者实现。在您的套接字上设置超时,以便在特定时间段内没有输入时抛出异常。

这是来自javadoc on Socket 的引用,注意它将从套接字读取的行为描述为阻塞操作,直到达到超时:

public void setSoTimeout(int timeout)
                  throws SocketException

使用指定的超时时间启用/禁用SO_TIMEOUT,以毫秒为单位。将此选项设置为 非零超时,对与关联的 InputStream 的 read() 调用 这个 Socket 只会阻塞这段时间。如果超时 过期,引发 java.net.SocketTimeoutException,尽管 套接字仍然有效。必须在输入之前启用该选项 阻塞操作生效。超时时间必须 > 0。A 零超时被解释为无限超时。

解决办法:

除了检查 -1 之外还可以。在套接字上设置超时,并确保正确处理抛出的异常。

【讨论】:

  • 这能确保我得到流中的所有内容吗?我正在考虑另一种方法,如果读取的字节不等于缓冲区的大小,则中断表示读取已到达流的末尾。这也是一种安全的方法吗?如果您仍然建议超时,那么可接受的时间量是多少?
  • 我认为这不是一个好的方法。您有一条通过套接字发送的消息,并且很可能它具有固定大小。除非您的消息大小不同,否则我看不出如何获得不同数量的字节。
  • 我的想法是,如果一条消息比BUF_SIZ 大,它将首先读取BUF_SIZ 数量,如果它在消息的末尾,它将读取小于BUF_SIZ。但是我确实看到了一个问题,如果消息大小是BUF_SIZ 的倍数。至于超时量,允许数据流进入的合理时间是多少
  • 我认为没有推荐的具体数字取决于应用程序的要求。但您也不想让连接保持打开太久。
  • 感谢您的意见。我选择了您的回复作为答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-29
  • 1970-01-01
相关资源
最近更新 更多