2015-05-20 251 views
2

我在wifi网络上有一个套接字客户端(在android手机上)和服务器(在PC上),并且服务器成功地从客户端读取数据。Java serversocket未检测到丢失连接

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

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

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

的netstat -na | grep的6668

TCP 192.168.43.202:6668 192.168.43.26:43076 ESTABLISHED

有没有办法告诉如果客户端主机已经消失,或者让读超时?

这里是服务器读取

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()); 
} 
+0

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

回答

0

这是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(); 
+0

正如在帖子中提到的,我设置了一个SoTimeout值,但读取没有超时。此外保持活动设置是为客户端而不是服务器。 – PerceptualRobotics

+0

错误,你在两个陈述中都是错误的。保持活跃是由服务器使用的机制,并且从上面的代码您还没有设置读取超时。我将添加编辑来回答以澄清这一点。 – John

+0

啊,是的,我在看ServerSocket类。谢谢,我会尝试。 – PerceptualRobotics

0

超时,让我们假设没有数据已发送10分钟,在60秒内关闭它!

Setting a timeout for socket operations

对于这个问题可以帮助你的答案。

+0

正如在帖子中提到的,我确实设置了SoTimeout值,但读取没有超时。 – PerceptualRobotics

+0

好吧,我看到这个链接有不同的方式来设置这个超时。检查出来,这可能会有所帮助!我刚刚测试过它,它工作正常。 –