在我的Java应用程序中,我有一个TCP服务器,它将在我的应用程序中生成的数据发送到所有连接的客户端。对于每个新套接字,我创建一个新线程。以下是线程代码。
public void run() {
try {
PrintStream printStream = new PrintStream(socket.getOutputStream(), true);
while (true) {
if (socket.isClosed()) {
break;
}
synchronized (DataSource.getInstance()) {
printStream.println(DataSource.getInstance().getData());
try {
DataSource.getInstance().wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
数据生成线程会DataSoure
在有新数据可用时进行写操作并进行调用,notifyAll()
以便处理连接套接字的所有线程醒来并将可用数据发送给客户端。
我的问题是,即使客户端断开连接,也socket.isClosed()
返回true。因此,处理套接字的线程永远不会终止。
为什么会这样?客户端断开连接后如何退出线程?
TCP没有“断开连接”。对等方只能表明它不想再发送任何信息(发送FIN),但这并不意味着它不希望接收任何信息。另一端仅意识到尝试读取并获得RST后也不需要读取。
如果将“不想读”作为客户端关闭的指示(如果应用程序协议是这种方式,则可能会这样做),则可以通过简单地从套接字读取来测试对等方是否“断开连接”。然后,系统调用不返回任何错误,但返回0个字节,这意味着将不再有来自对等方的数据。在Java中,这种情况被转换为EOFException。
除此之外,套接字不会自动关闭-仅显式关闭。isClosed
仅在套接字在本地端(而不是对等端)上显式关闭后,才返回true。并且isConnected
也不会告诉您另一端是否“断开连接”,它只会告诉您另一端是否确实连接了对等端。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句