在让客户知道的同时,从服务器端关闭TCP连接

时间:2012-01-09 14:36:57

标签: java sockets tcp

我在服务器端为每个连接都有一个线程。当客户端没有发送命令时,服务器线程阻塞:

while ((commandHeader = fromNode.readLine()) != null) {

在内部调用从TCP套接字获得的OutputStream上的readLine()。 当我从另一个线程调用socket.close()时,这个调用用SocketException唤醒,并且线程可以被终止。

但是,如果客户端没有醒来并决定发出命令,则执行

stream.writeBytes("something\n");

无限期阻止。我知道这对TCP来说可能很好(它只是半关闭。) 我应该在退出时向客户发送一些东西,比如“退出\ n”;它也可以只读一个EOF。但是,如果在发送命令之前在客户端上调用readLine()或其他读取操作,则在连接未关闭时它们会阻止等待数据。 在尝试写入连接之前,客户端如何检测到连接已经半关闭?

2 个答案:

答案 0 :(得分:3)

在服务器上调用socket.close()时,底层TCP连接将使用典型的FIN / FIN-ACK序列和RST数据包关闭,因此客户端将知道。当客户端之后调用stream.writeBytes()时,它应该失败。如果没有,则意味着丢失了一些数据包,最终连接最终都会失败。

答案 1 :(得分:2)

首先,我认为您的应用程序逻辑应该是这样的,以避免半开TCP连接。您可以考虑在客户端添加计时器,这样如果没有收到任何计时器,它会再次开始轮询服务器。

从服务器的角度来看,另一个选择是在readLine上设置计时器。为readLine设置另一个设置计时器的方法,如果超出一定时间,只需将一些默认值返回到while循环。

编辑:

您可能需要read this article特别是该部分: IO上阻止的线程怎么样?