【问题标题】:Java Sockets nonblocking readJava Sockets 非阻塞读取
【发布时间】:2010-08-23 20:18:19
【问题描述】:

我正在使用 DataInputStream 从套接字读取字符/数据。

我想使用 .readUnsignedShort();如果没有 2 个字节要读取,则让它抛出异常。我应该继承 DataInputStream 并覆盖添加异常的方法,还是有更简单的方法?

【问题讨论】:

    标签: java sockets


    【解决方案1】:

    如果您想要快速而肮脏的东西,请尝试inputStream.available()

    if (stream.available() < 2) {
        // throw it
    }
    

    如果你想在数据可用时实现真正的非阻塞读取和回调,我认为 Pablo 的答案更好。

    【讨论】:

    • 我通过谷歌搜索“非阻塞套接字”发现了这一点,但我真正想要的只是轮询套接字以获取传入数据而不阻塞线程。没想到这么简单,谢谢。
    【解决方案2】:

    我认为 Java NIO 非阻塞类是你最好的选择。查看SocketChannel类及其相关代码示例。

    但是请注意,当您发出读取命令时,可能会出现字节不可用的情况,但这并不意味着将永远到达您的套接字...

    【讨论】:

      【解决方案3】:
      void readButDoNotBlockForALongTime(java.net.Socket socket) {
          int someTimeout = 1000;
          socket.setSoTimeout(someTimeout);
          try {
              // read as much as you want - blocks until timeout elapses
          } catch (java.net.SocketTimeoutException e) {
              // read timed out - you may throw an exception of your choice
          }
      }
      

      这是一种简单的方法,只要您愿意就可以阻止。

      setSoTimeout(int timeout):启用/禁用具有指定超时时间的 SO_TIMEOUT,以毫秒为单位。将此选项设置为非零超时,与此 Socket 关联的 InputStream 上的 read() 调用将仅阻塞此时间量。如果超时到期,则会引发 java.net.SocketTimeoutException,尽管 Socket 仍然有效。必须在进入阻塞操作之前启用该选项才能生效。超时必须 > 0。超时为零被解释为无限超时。

      如需更优雅的解决方案,您可以考虑使用 NIO。

      【讨论】:

      • 我不认为每 1000 毫秒抛出和捕获一个异常是优雅的
      • 没错。这比打开程序进行DOS攻击要好,但使用NIO会更好。
      • 我同意,@StealthRabbi。去掉优雅二字。 :)
      【解决方案4】:

      如果输入在提供两个字节之前结束,它将抛出 EOFException。如果没有输入 available() 将返回零,但如果在某些情况下(例如 SSL)有 is 输入,它也可以返回零。

      【讨论】:

        猜你喜欢
        • 2011-03-20
        • 1970-01-01
        • 2021-01-03
        • 2014-11-17
        • 2015-05-05
        • 2014-04-24
        • 2017-02-18
        • 1970-01-01
        相关资源
        最近更新 更多