【问题标题】:Java serversocket not detecting lost connectionJava serversocket 未检测到丢失的连接
【发布时间】:2015-05-21 02:25:38
【问题描述】:

我在 wifi 网络上有一个套接字客户端(在 android 手机上)和服务器(在 PC 上),服务器成功地从客户端读取数据。

但是,当我关闭手机上的 wifi 时,服务器读取只是挂起,而我希望会引发一些错误。

我确实在服务器上设置了 setSoTimeout,但读取没有超时。

在 PC 上 netstat 仍然显示已建立的连接

netstat -na | grep 6668

TCP 192.168.43.202:6668 192.168.43.26:43076 已建立

有没有办法判断客户端主机是否已消失,或者读取是否超时?

这是服务器读取

 if (ss.isConnected()) {
            try {
                readData();
            } catch (java.net.SocketTimeoutException ex) {
                logger.warning(ex.toString());
            } catch (InterruptedIOException ex) {
                logger.warning(ex.toString());
            } catch (IOException ex) {
                logger.log(Level.WARNING, "Data communication lost will close streams - IOEx - socket status {0}", ss.socketStatus());
                closeStreams();
            } catch (Exception ex) {
                logger.log(Level.WARNING, "Data communication lost will close streams - Ex - socket status {0}", ss.socketStatus());
                                    closeStreams();
            }

        }

readData 在哪里,

public void readData() throws IOException {
    for (int i = 0; i < data.length; i++) {
        data[i] = ss.readDouble();
    }
}

ss.readDouble() 是,

public double readDouble() throws IOException {
    return in.readDouble();
}

还有服务器连接,

public void connect() throws IOException {
    if (serverSocket == null || serverSocket.isClosed()) {
        init();
    }
    logger.log(Level.INFO, "Wait on " + serverSocket.getLocalPort());
    server = serverSocket.accept();
    serverSocket.close();

    logger.log(Level.INFO, "Connected to {0}", server.getRemoteSocketAddress());
    out = new DataOutputStream(server.getOutputStream());
    in = new DataInputStream(server.getInputStream());
}

【问题讨论】:

  • 为什么每次接受连接时都关闭服务器套接字?不要那样做。

标签: java android sockets networking serversocket


【解决方案1】:

超时,假设10分钟没有数据发送,60秒后关闭!

Setting a timeout for socket operations

这个问题的答案可能会对你有所帮助。

【讨论】:

  • 如帖子中所述,我确实设置了 SoTimeout 值,但读取不会超时。
  • 好的,我看到这个链接有不同的方式来设置这个超时。看看吧,也许有帮助!我刚才测试了一下,效果很好。
【解决方案2】:

这是 TCP 连接的本质,而不是 Java 套接字本身。如果远程对等点因连接中断而断开连接,您的服务器应该如何知道对等点根本没有数据要发送?

在关闭的套接字上写会导致异常,如果客户端没有正确结束 tcp 连接,读取将简单地阻塞,原因如上所述。

如果你通过套接字 API,你会发现设置超时的选项(在进行阻塞操作之前)。

您还可以考虑 TCP KEEP Alive,它也由 Socket API 公开。

// 编辑:根据 OP 注释的附加信息

当您的客户端连接到服务器时,您会创建一个客户端套接字来与对等方通信。您的服务器套接字是您正在侦听新客户端连接的套接字。它是您指定保持活动或读取超时的客户端套接字,因为这是您从中读取/写入的套接字。

// your server is actually reference to ClientSocket
 server = serverSocket.accept();

// keep alive duh
    server.setKeepAlive(true);

serverSocket.close();

【讨论】:

  • 如帖子中所述,我确实设置了 SoTimeout 值,但读取不会超时。此外,保持活动设置适用于客户端而不是服务器。
  • Err,你在这两个陈述上都错了。保持活动也是服务器使用的机制,并且从上面的代码中您也没有设置读取超时。我将添加编辑以回答您的问题。
  • 啊,是的,我正在查看 ServerSocket 类。谢谢,我试试看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 1970-01-01
  • 2018-09-26
  • 2016-09-04
  • 2011-06-13
相关资源
最近更新 更多