我正在构建一个客户端 - 服务器应用程序,我必须实现一个keepalive机制,以便检测客户端是否崩溃。我在客户端和服务器端都有单独的线程。客户端线程发送“ping”然后休眠3秒,同时服务器读取BufferedInputStream
并检查是否收到ping,如果是,则使ping计数器等于零,否则它将计数器递增+1,服务器线程然后休眠3秒,如果ping计数器达到3,它会将客户端声明为死。
问题是当服务器读取输入流时,它是一个阻塞调用,并且它会一直阻塞,直到收到下一个ping,无论它有多延迟,所以服务器永远不会检测到错过的ping。
任何建议,以便我可以读取流的当前值,如果传入流上没有任何内容,则不会阻止。
谢谢,
答案 0 :(得分:5)
Java 1.4引入了由java.nio
包表示的非阻塞I / O的概念。这可能就是你所需要的。
请参阅this tutorial for how to use non-blocking I/O。
另外,假设这不是家庭作业或学习练习,那么我建议使用更强大的协议框架,例如Apache Mina或JBoss Netty,而不是从头开始构建这些东西。请参阅它们之间的this comparison以及您希望使用它们的原因。
答案 1 :(得分:0)
您可以拥有一个单独的监控线程来监控所有阻塞连接。当连接收到任何内容时,它可以重置计数器。 (我会将任何数据包视为心跳一样好)您的监控线程每次运行时都会递增此计数器,当它达到限制时(即因为它没有重置为零),您可以关闭连接。你只需要一个这样的线程。在刚关闭的连接上阻塞的线程抛出IOException,唤醒线程。
另一方面,只要数据包在一段时间内没有被发送,就可以触发心跳。这意味着繁忙的连接不会发送任何心跳,它应该不需要。