Java Sockets 非阻塞读取

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3551337/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 02:22:21  来源:igfitidea点击:

Java Sockets nonblocking read

javasockets

提问by clarity

I'm using a DataInputStream to read characters/data from a socket.

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

I want to use .readUnsignedShort(); and have it throw an exception if there isn't 2 bytes to read. Should I subclass the DataInputStream and override the methods adding the exceptions, or is there an easier way?

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

回答by NG.

If you want something quick and dirty, try inputStream.available().

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

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

If you want true non blocking reads and callbacks when data is available, I think Pablo's answer is better.

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

回答by Pablo Santa Cruz

I think Java NIO non-blocking classes are your best choice. Check SocketChannelclass and its related code samples.

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

But be careful, when you issue your read command, it might be the case that bytes are not available yet, but that doesn't mean that the will neverarrive to your socket...

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

回答by Zsolt Safrany

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
    }
}

This is a simple way to block for only as long as you want.

这是一种简单的方法,可以根据需要阻止。

setSoTimeout(int timeout): Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect. The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout.

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

For a more elegant solution, you may consider using NIO.

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

回答by user207421

If the input ends before supplying two bytes it will throw EOFException. If there is no input available() will return zero, although it can also return zero if there isinput in some circumstances (e.g. SSL).

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