我用Java编写了一个tcp服务器。它生成工作者实例(Runnable)并侦听传入的tcp连接。从客户端连接后,它将从客户端接收数据并进行自己的处理。
最近,我注意到在客户端断开连接时,整个服务器将崩溃并出现错误java.net.SocketException:当客户端断开连接或退出时连接重置。这是我意识到我没有彻底测试所有失败实例的tcp服务器。
我查看了代码并注意到tcp服务器将在此行崩溃而(工作者实例中的(bytesRead .... -1)
final int BUFFSIZE = 65535;
int bytesRead;
byte[] buffer = new byte[BUFFSIZE];
din = new BufferedInputStream(clientSocket.getInputStream());
while ((bytesRead = din.read(buffer)) != -1) { //tcp server crashes at this line if client quits or disconnects.
// worker does its job.
}
我一直在思考关闭工作器实例而不会导致tcp服务器崩溃的最佳方法。我没有访问客户端源代码来修改它们的任何内容。
有什么想法吗?
Bregs Yakult121
答案 0 :(得分:2)
如果要处理异常,则应在try / catch块中完成网络I / O.
答案 1 :(得分:2)
如果连接已关闭,此行应抛出IOException。只需确保捕获IOException并在Runnable发生时从run()
方法返回。这将停止处理此客户端连接的线程。
但是,如果它破坏整个服务器,你必须做错了。这可能意味着您没有每个客户端连接的线程,而是按顺序处理客户端的单个线程,一次一个。发布服务器代码以获取更多信息。
答案 2 :(得分:1)
找出问题所在。写下我为任何想要解决同样问题的人所做的事情。
private boolean isStopped = false;
while (!isStopped()) {
try {
while ((bytesRead = din.read(buffer)) != -1) {
// worker does its job.
}
}
catch (IOException ex) {
System.out.println("Exception called! Most likely due to client disconnect!");
stop();
}
}
public boolean isStopped() {
return this.isStopped;
}
public synchronized void stop(){
this.isStopped = true;
}