用Java实现keepalives
我正在构建一个客户机-服务器应用程序,在这个应用程序中,我必须实现一个keepalive机制,以便检测客户机是否崩溃。我在客户端和服务器端都有单独的线程。客户端线程发送一个ping,然后休眠3秒,而服务器读取BufferedInputStream并检查是否接收到ping,如果接收到ping,则使ping计数器等于零,否则使计数器增加+1,服务器线程然后休眠3秒,如果ping计数器达到3,则声明客户端为死 问题是,当服务器读取输入流时,这是一个阻塞调用,它会阻塞直到接收到下一个ping,而不管延迟的程度如何,因此服务器永远不会检测到错过的ping 任何建议,这样我就可以读取流的当前值,如果传入流中没有任何内容,它就不会阻塞用Java实现keepalives,java,inputstream,keep-alive,Java,Inputstream,Keep Alive,我正在构建一个客户机-服务器应用程序,在这个应用程序中,我必须实现一个keepalive机制,以便检测客户机是否崩溃。我在客户端和服务器端都有单独的线程。客户端线程发送一个ping,然后休眠3秒,而服务器读取BufferedInputStream并检查是否接收到ping,如果接收到ping,则使ping计数器等于零,否则使计数器增加+1,服务器线程然后休眠3秒,如果ping计数器达到3,则声明客户端为死 问题是,当服务器读取输入流时,这是一个阻塞调用,它会阻塞直到接收到下一个ping,而不管延迟
谢谢,Java1.4引入了非阻塞I/O的思想,由Java.nio包表示。这可能是你需要的 看
另外,假设这不是家庭作业或学习练习,那么我建议使用更健壮的协议框架,比如or,而不是从头开始构建这些东西。查看它们之间的关系以及使用它们的原因。您可以有一个单独的监视线程来监视所有阻塞连接。当连接收到任何信息时,它可以重置计数器。我会将任何数据包视为心跳,您的监控线程可以在每次运行时增加此计数器,并且当它达到限制时(即,因为它没有重置回零),您可以关闭连接。你只需要一根这样的线。阻塞您刚刚关闭的连接的线程抛出IOException,唤醒该线程
另一方面,只要数据包在一段时间内没有发送,就会触发心跳。这意味着一个繁忙的连接不发送任何心跳,它不需要发送任何心跳。您能解释一下服务器从未检测到丢失的ping吗?例如,客户端每3秒发送一次keep-alives,服务器也每3秒检查一次keep-alives。现在假设客户端在10秒钟内没有发送keep-alive,那么当服务器检查keep-alive时,它不会读取任何内容,因为客户端没有发送任何内容,所以从流读取的调用将被阻止,直到它在10秒钟后收到下一个keepalive,此时服务器将很高兴地声明它收到了keepalive。因此,它永远不会检测到丢失的“继续生存”。