socket仅在Java TCP服务器输出上检查客户端断开连接
我有一个Java TCP服务器,当客户端连接到它时,它每30秒向客户端输出一条消息。严格要求客户端不向服务器发送任何消息,并且服务器不向客户端发送30秒间隔消息以外的任何数据
当我断开客户端连接时,服务器在下次尝试写入客户端之前不会意识到这一点。因此,服务器识别断开连接可能需要30秒
我想做的是每隔几秒钟检查一次断开连接,而不必等待,但我不确定如何执行此操作,因为a)服务器没有从客户端接收到数据,b)服务器无法发送任何其他数据。有人能解释一下吗?谢谢
# 1 楼答案
如果您管理多个客户端,那么我猜您将使用非阻塞套接字(如果没有,则考虑使用非阻塞)。您可以使用选择器监视所有连接的套接字,以检查它们是否可读或可写,或者该套接字上是否存在错误。当某些客户端断开连接时,选择器将标记该套接字并返回。 有关更多帮助,请使用谷歌“套接字选择函数”
# 2 楼答案
即使您的服务器没有从客户端“接收”,客户端套接字上的非阻塞读取也会告诉您没有要读取的内容(如您所期望的),或者客户端已断开连接
如果您使用的是NIO,那么只需使用一个非阻塞
Selector
循环(带有非阻塞套接字),并且只需在30秒的标记上进行写入。如果SelectionKey
是可读的,并且SocketChannel
上的读取返回-1,则您知道客户端已断开连接编辑:另一种阻塞方法是只需选择30秒超时。任何客户端断开连接都会导致select返回,您将通过读取集知道哪些是select。您需要做的另一件事是跟踪您在选择中被阻止的时间,以确定何时在30秒标记上进行写入(将下一次选择的超时设置为增量)
大编辑:与Myn交谈后,提供完整示例:
这里值得注意的是
PrintWriter
确实使您远离实际的套接字,而且您不会在写入时捕获套接字断开连接(它永远不会引发异常,您必须手动使用checkError()
检查它),您可以改为使用BufferedWriter
(需要使用flush()
来推送输出),并像BufferedReader
一样处理它以捕获写入时的disco