2010-08-23 63 views
3

我正在使用DataInputStream从套接字读取字符/数据。非插入式Java套接字读取

我想使用.readUnsignedShort();并且如果没有2个字节的话,它会抛出一个异常。我应该继承DataInputStream并重写添加异常的方法,还是有更简单的方法?

回答

7

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

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

如果你想在数据可用时进行真正的非阻塞式读取和回调,我认为巴勃罗的答案更好。

+1

我发现这个通过google搜索“非阻塞套接字”,但我真正想要的是轮询套接字传入的数据没有阻塞线程。认为它会非常简单,谢谢。 – cib 2012-02-04 15:37:07

3

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

但要小心,当你发出你的读命令时,它可能是字节尚未公布的情况,但这并不意味着会从未到达您的插座......

0

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

2
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。

+3

我不认为有一个例外会被抛出并且每隔1000毫秒被捕获很高雅 – 2015-08-28 11:37:57

+0

正是如此。这比打开DOS攻击程序要好,但使用NIO会更好。 – MauganRa 2016-11-25 08:54:35

+0

我同意,@StealthRabbi。删除优雅的词。 :) – 2016-12-04 20:03:44