【问题标题】:Java detect disconnect from Server in ClientJava 在客户端检测与服务器的断开连接
【发布时间】:2014-10-09 19:11:06
【问题描述】:

我制作了一个具有客户端和服务器端的 java 应用程序。双方通过套接字进行通信。在我的服务器应用程序被某些东西杀死并且无法关闭或关闭服务器套接字之前,此方法效果很好。

客户端似乎没有注意到断开的连接,只是在尝试读取下一个对象时挂起。

我还尝试每 5 秒从客户端发送一个测试对象以检测服务器是否离线,但这也不起作用。

我可能不得不提到,这只发生在 Windows 上运行服务器应用程序和 Linux 上的客户端(VirtualBox 中的 Ubuntu)时。 Windows-Windows 工作正常。 Netstat 甚至在 Linux 上给了我一个 ESTABLISHED,虽然我已经杀死了服务器。

客户端代码:

requestSocket = new Socket("192.168.1.3", 1234);
out = new ObjectOutputStream(new CipherOutputStream(requestSocket.getOutputStream(), ec));

in = new ObjectInputStream(new CipherInputStream(requestSocket.getInputStream(), dc));

new Thread() {
    public void run() {
        while(true) {
            try {
                out.writeObject(obj);
                out.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println("sent");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {}
        }
    }
}.start();

服务器代码:

serverSocket = new ServerSocket(1234);
socket = serverSocket.accept();
out = new ObjectOutputStream(new CipherOutputStream(clientSocket.getOutputStream(), ec));
in = new ObjectInputStream(new CipherInputStream(clientSocket.getInputStream(), dc));

//do-while-reading on the socket[...]

我阅读了多个线程,这些线程告诉我如何检测服务器端丢失的连接,但没有发现客户端的连接,或者答案对我不起作用。

【问题讨论】:

  • 据我了解,如果服务器端监听套接字它仍然绑定,要么应用程序在崩溃时实际上并没有完全退出,如果它有端口应该被操作系统释放,或者服务器的子进程仍在运行。如果后者为真,则即使绑定它的进程已终止,该端口仍可能被绑定,因为子进程仍在运行。您的服务器是否产生子进程?如果服务器实际上已经退出,您应该通过尝试写入套接字客户端的输出流来接收异常。
  • 关闭服务器应用程序后,Windows 上的 Netstat 不显示任何连接。所以我猜端口不再绑定,对吗?另外,是的,我通过 javafx 为每个新连接生成一个子线程/任务。
  • @blkchockr Windows can hold connections open 当仍有数据要发送时。你测试过 Linux-Linux 吗?
  • 我还没有测试 Linux-Linux,因为我的服务器至少需要 JDK 8u40 才能运行,因为使用了一些 javafx 东西,而且我还没有考虑在 Linux 上安装早期版本。在您提到的帖子中,作者正在谈论几分钟并且有数据要读取,但是我在每次写入后刷新我的流并且还等待了将近一个小时。我会尽快测试 Linux-Linux,但我也希望能够进行跨平台连接!

标签: java sockets cross-platform disconnect


【解决方案1】:

在套接字上设置读取超时,持续时间合适,足以包括所有正常传输,并捕获SocketTimeoutException.

【讨论】:

  • 这对我来说不是一个真正的选择,因为输入通常是在服务器应用程序上进行的。由于这种方案,我需要与服务器保持恒定连接,并在丢失后立即尝试重新连接。
  • 好的,所以如果你只是在写,抓住IOException 并把它当作连接被软管的信号。唯一的IOException 并不意味着SocketTimeoutException
  • 我的问题是我没有得到任何异常。然后流就在阅读时挂断了自己,没有注意到已经没有连接了。
【解决方案2】:

问题似乎出在虚拟机上。在我的笔记本电脑上使用 Manjaro Linux 进行测试时,一切正常!

无论如何,感谢您的贡献。 :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    相关资源
    最近更新 更多