InputStream
,OutputStream
和Socket
)然后我如何通知
关于断线的另一端?我知道有一种方法 - 尝试阅读InputStream
,
如果连接关闭,它会抛出IOException
,但还有其他方法可以检测到这个吗?inputStream.available()
没有解决这个问题。那是为什么? 附加信息:我要求采用另一种方式,因为如果我必须尝试从
InputStrem
检测断开连接。
答案 0 :(得分:6)
尝试从抛出IOException的InputStream中读取
这是不正确的。如果对等方关闭套接字:
read()
返回-1 readLine()
返回null readXXX()
会针对任何其他X投掷EOFException
。由于InputStream
只有read()
个方法,它只返回-1:它不会在EOS中抛出IOException
。
与此处的其他答案相反,没有TCP API或Socket方法可以告诉您对等方是否已关闭连接。你必须尝试阅读或写作。
您应该使用读取超时。
InputStream.available()
无法解决问题,因为它不会返回任何类型的EOS指示。它的正确用法很少,而且不是其中之一。
答案 1 :(得分:0)
问题不在于“如果服务器/客户端关闭连接”。问题是“如果他们没有关闭连接然后连接断开怎么办?”
如果没有自己的心跳协议,就无法检测到它。
另一种选择是将SO_KEEPALIVE设置为true。
“为TCP套接字设置keepalive选项,并且在任一方向上没有数据在套接字上交换2小时(注意:实际值取决于实现)”
根据我的经验,它比每2小时要快得多。更像是~5分钟。除了使用So_KEEPALIVE之外,你还是被搞砸了:P
在我的通信协议中,我使用每2秒发送的保留“心跳”字节。我自己的filterInputStream和filterOutputStream发送/并摘要心跳字节。
答案 2 :(得分:0)
在连接断开的那一刻,没有O-O-O方式来获得回调/异常。只有在套接字流上进行显式读/写操作时,才能了解断开的连接。
有两种方法可以从套接字中读取即可。它们到达时逐字节同步读取;或等待直到流上可用的所需字节数,然后进行批量读取。您可以通过调用套接字流上的available()来进行检查,它会为您提供当前可用于读取的字节数。在第二种情况下,如果套接字连接由于某种原因而中断,则无法通知您。在这种情况下,您需要使用超时机制来等待。在第一种情况下,您进行显式读/写操作会得到异常。
答案 3 :(得分:0)
Q1如果关闭服务器上的套接字连接,客户端应该立即抛出异常,当然是在下一次读取尝试时,反之亦然。
Q2来自JavaDocs
返回可以读取的字节数的估计值(或 从此输入流中跳过)而不会被下一个阻塞 调用此输入流的方法。下一次调用 可能是同一个线程或另一个线程。单个读取或跳过 这么多字节不会阻塞,但可以读取或跳过更少的字节。
这不是当前流中字节数的指示,而是对可从实现中读取的不会阻塞当前线程的字节数的估计