Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 关闭服务器端的TCP连接,同时让客户端知道_Java_Sockets_Tcp - Fatal编程技术网

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

Java 关闭服务器端的TCP连接,同时让客户端知道,java,sockets,tcp,Java,Sockets,Tcp,服务器端的每个连接都有一个线程。当客户端不发送命令时,服务器线程将阻塞: while ((commandHeader = fromNode.readLine()) != null) { 它在从TCP套接字获取的OutputStream上内部调用readLine()。 当我从另一个线程调用socket.close()时,这个调用会被SocketException唤醒,线程可以终止 但是,如果一个客户端唤醒并决定发出一个命令,它就会执行 stream.writeBytes("something\n

服务器端的每个连接都有一个线程。当客户端不发送命令时,服务器线程将阻塞:

while ((commandHeader = fromNode.readLine()) != null) {
它在从TCP套接字获取的OutputStream上内部调用readLine()。 当我从另一个线程调用socket.close()时,这个调用会被SocketException唤醒,线程可以终止

但是,如果一个客户端唤醒并决定发出一个命令,它就会执行

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

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

从服务器的角度来看,另一个选项是在读取线上设置计时器。为readLine创建另一个方法,在该方法中设置计时器,如果超过某个时间,只需向while循环返回一些默认值

编辑:

您可能需要特别注意以下部分:当在服务器上调用socket.close()时,IO上阻塞的线程如何?

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