我正在开发客户端服务器应用程序,当通过套接字收到停止消息时,我想关闭服务器。我的服务器的代码看起来像这个
public class Server extends Thread {
private AtomicBoolean running = new AtomicBoolean(true);
public synchronized void setRunning(boolean value){
running.set(value);
}
public void run(){
while(running.get()){
try {
clientSocket = serverSocket.accept();
//doing stuff...
}catch (IOException e) {
logger.error("{} n",e.getMessage());
}
}
正在运行的变量是在另一个处理我的消息的类中设置的。函数是这样写的
public synchronized void onReceive(Message message){
if(message.equals(stopMessage)){
server.setRunning(false);
for(Client c : clients)
c.shutdown();
server.shutdown();
}
}
我的问题是,服务器中的while循环在将运行变量设置为false之前又执行了一次迭代,并且服务器试图检查套接字,即使它为null,因为连接到该套接字的客户端已经关闭(客户端也是一个线程(。我做错了什么,但我不知道是什么。有什么想法吗?非常感谢。
这样更改while
循环:
while( running.get() )
{
try( clientSocket = serverSocket.accept() )
{
if( !running.get() ) break;
//doing stuff...
}
catch( SocketTimeoutException e )
{
continue;
}
catch( SocketException e )
{
if( !serverSocket.isClosed() ) logger.error( "{} n", e.getMessage() );
break;
}
catch( IOException e )
{
logger.error( "{} n", e.getMessage() );
break;
}
}
循环在serverSocket.accept()
中等待,并且将仅在传入连接或超时时继续。更改running
不会唤醒它,因此它只在while
循环的下一个循环中识别该更改。
在出现错误异常之后,您不应该继续循环。即使在SocketTimeoutException
的情况下,continue
也可能不正确/不充分。