Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.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 如何检测远端插座关闭?_Java_Networking_Sockets_Tcp - Fatal编程技术网

Java 如何检测远端插座关闭?

Java 如何检测远端插座关闭?,java,networking,sockets,tcp,Java,Networking,Sockets,Tcp,如何检测是否在远程端的套接字上调用了Socket#close()。isConnected方法没有帮助,即使远程端关闭了套接字,它也会返回true。试试这个: public class MyServer { public static final int PORT = 12345; public static void main(String[] args) throws IOException, InterruptedException { ServerSocke

如何检测是否在远程端的套接字上调用了
Socket#close()

isConnected方法没有帮助,即使远程端关闭了套接字,它也会返回
true
。试试这个:

public class MyServer {
    public static final int PORT = 12345;
    public static void main(String[] args) throws IOException, InterruptedException {
        ServerSocket ss = ServerSocketFactory.getDefault().createServerSocket(PORT);
        Socket s = ss.accept();
        Thread.sleep(5000);
        ss.close();
        s.close();
    }
}

public class MyClient {
    public static void main(String[] args) throws IOException, InterruptedException {
        Socket s = SocketFactory.getDefault().createSocket("localhost", MyServer.PORT);
        System.out.println(" connected: " + s.isConnected());
        Thread.sleep(10000);
        System.out.println(" connected: " + s.isConnected());
    }
}
启动服务器,启动客户端。您将看到它打印“connected:true”两次,即使第二次关闭套接字也是如此


真正找到答案的唯一方法是在相关的输入/输出流上读取(返回值为-1)或写入(抛出
IOException
(断管)。

在写入客户端套接字时,还可以检查套接字输出流错误

out.println(output);
if(out.checkError())
{
    throw new Exception("Error transmitting data.");
}

由于答案有偏差,我决定对此进行测试并公布结果——包括测试示例

这里的服务器只是将数据写入客户端,不需要任何输入

服务器:

ServerSocket serverSocket = new ServerSocket(4444);
Socket clientSocket = serverSocket.accept();
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
while (true) {
  out.println("output");
  if (out.checkError()) System.out.println("ERROR writing data to socket !!!");
  System.out.println(clientSocket.isConnected());
  System.out.println(clientSocket.getInputStream().read());
        // thread sleep ...
  // break condition , close sockets and the like ...
}
  • clientSocket.isConnected()在客户端连接后(甚至在断开连接后)始终返回true
  • getInputStream().read()
    • 只要客户端连接,线程就会等待输入,因此程序不会执行任何操作,除非您得到一些输入
    • 如果客户端断开连接,则返回-1
  • 一旦客户端断开连接,out.checkError()就为true,因此我建议这样做

如果远程系统已断开/关闭连接,那么方法Socket.Available将立即引发SocketException。

在您的示例中,服务器未正常关闭TCP连接(RST已发送,仅此而已)。如果在客户端套接字上调用close(),则连接将正常关闭。从读取操作的不同结果可以看出这一点:SocketException抛出与读取返回-1.BTW,感谢您提醒我Java套接字工作方式中的“奥秘”。结果,我又问了一个后续问题:找到答案的唯一方法就是写作。从突然关闭的套接字读取可能并不总是返回-1@Pacerier,请参阅我发布的链接。本质上,不发送任何内容的连接和死机的连接(如果您不使用TCP保持活动状态)之间没有区别。您只能通过写入来检测关闭的连接。为什么会有这么多的UpVote:/它实际上甚至不回答问题,它只是解释什么不起作用……当写入时检测到错误时,checkError()立即为真。它当然不会在客户端断开连接时立即变为现实-不,不会的。错。错。错误信息。你可以,但你不一定马上就能得到。