简体   繁体   English

Java套接字非阻塞读取

[英]Java Sockets nonblocking read

I'm using a DataInputStream to read characters/data from a socket. 我正在使用DataInputStream从套接字读取字符/数据。

I want to use .readUnsignedShort(); 我想使用.readUnsignedShort(); and have it throw an exception if there isn't 2 bytes to read. 如果没有要读取的2个字节,则抛出异常。 Should I subclass the DataInputStream and override the methods adding the exceptions, or is there an easier way? 我应该继承DataInputStream并覆盖添加异常的方法,还是有更简单的方法?

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的答案更好。

I think Java NIO non-blocking classes are your best choice. 我认为Java NIO非阻塞类是您的最佳选择。 Check SocketChannel class and its related code samples. 检查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 never arrive to your socket... 但是要小心,当你发出你的读命令时,可能是字节不可用的情况,但这并不意味着它永远不会到达你的套接字......

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. setSoTimeout(int timeout):使用指定的超时启用/禁用SO_TIMEOUT,以毫秒为单位。 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. 如果将此选项设置为非零超时,则与此Socket关联的InputStream上的read()调用将仅阻止这段时间。 If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. 如果超时到期,则引发java.net.SocketTimeoutException,尽管Socket仍然有效。 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. 超时必须> 0.超时为零被解释为无限超时。

For a more elegant solution, you may consider using NIO. 要获得更优雅的解决方案,您可以考虑使用NIO。

If the input ends before supplying two bytes it will throw EOFException. 如果输入在提供两个字节之前结束,则会抛出EOFException。 If there is no input available() will return zero, although it can also return zero if there is input in some circumstances (eg SSL). 如果没有可用的输入()将返回零,虽然它也可以返回零,如果在某些情况下(如SSL)输入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM