在我的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();
}
}
Run Code Online (Sandbox Code Playgroud)
数据生成线程写入DataSoure
新数据可用时调用,notifyAll()
以便处理连接套接字的所有线程唤醒并向客户端发送可用数据.
我的问题是,即使客户端断开连接,也会socket.isClosed()
返回true.因此处理套接字的线程永远不会被终止.
为什么会这样?当客户端断开连接时,如何退出线程?
与TCP没有"脱节".对等体只能表明它不想再发送任何东西(发送FIN),但这并不意味着它不想接收任何东西.另一端只有在尝试读取并且获得RST后才意识到读取也是不需要的.
如果您将"不想阅读"作为客户端关闭的指示(如果应用程序协议是这样的话,那么您可以通过简单地从套接字读取来测试对等体是否"断开连接").系统调用然后返回没有错误但是0字节,这意味着将不再有来自对等体的数据.在Java中,这种情况被转换为EOFException.
除此之外,套接字不会自动关闭 - 只能显式关闭.isClosed
只有在本地端显式关闭套接字而不是对等端才会返回true.并且isConnected
也不会告诉你,如果另一端"断开连接",它只会告诉你你的终端是否连接到同伴.
另请参阅Java Socket API:如何判断连接是否已关闭?.
归档时间: |
|
查看次数: |
2531 次 |
最近记录: |