2016-11-13 117 views
2

我正在尝试创建多线程服务器,以便多个客户端可以连接并可以接受服务。但是,如果需要,我不确定如何正确释放我的资源。Java:正确关闭多线程服务器的套接字

我的服务器运行一个输入线程(等待用户输入)和一个处理线程(处理连接和用户)。我在服务器类中打开一个ServerSocket并将其传递给我的处理线程。它看起来像这样:

public class ClientConnector implements Runnable { 

private ServerSocket serverSocket; 

public ClientConnector(ServerSocket serverSocket) { 
    this.serverSocket = serverSocket; 
} 

@Override 
public void run() { 
    ExecutorService tcpExecutor = Executors.newCachedThreadPool(); 

    while (!serverSocket.isClosed()) { 
     Socket clientSocket = null; 

     try { 
      clientSocket = serverSocket.accept(); 
     } catch (IOException e) { 
      System.err.println("could not accept connection"); 
     } 

     if (clientSocket != null) { 
      tcpExecutor.execute(new ClientHandler(clientSocket); 
     }   
    } 
} 
} 

如果我要退出,我只是在我的服务器类运行这个方法来关闭的ServerSocket:

public void exit() { 
    try { 
     serverSocket.close(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

这应该引起接下来的ServerSocket.accept()调用抛出异常,并且由于套接字关闭,循环停止。

我的问题是 - 是否关闭ServerSocket隐式关闭使用它创建的ClientSockets?或者我应该确保手动关闭每一个打开的ClientSocket?如果是这样的话,有没有一种简单的方法可以做到这一点,而不是保存每一个连接到服务器的连接?

+0

问题是,在我们关闭服务器套接字时偶然发生的任何套接字都打开,因为它们被阻塞等待来自客户端的输入。他们是一种奇怪的封锁,甚至不能被打断。即使发送一个空数据包以解除阻塞套接字的技巧也不行,因为它们正在等待与第三方建立的连接,因此您无法在这些连接中插入空数据包。那么,你有没有找到解决办法? –

回答

0

是否关闭ServerSocket隐式关闭使用它创建的ClientSocket?

不,它对它们没有影响。

或者我应该确保手动关闭每一个打开的ClientSocket?

是的,你应该这样做,无论如何,在每个处理程序线程。

如果是这样,有没有一种简单的方法来做到这一点,而不是保存每个连接到服务器的某个地方?

只需强制读取超时并关闭超时的每个套接字。这是任何服务器的正常部分。您不必收集插座或采取任何特殊措施关闭它们。

0

不,它不。它只是关闭了ServerSocket意味着无法建立新的连接。现有的开放式套接字仍将继续工作。

没有“简单”的方法来关闭所有开放的套接字,因为它并不是真的很难开始(或者如果你发现作为网络编程中的一个难题,有一些奇怪的事情发生)。

0

让客户端处理程序线程在处理结束时关闭客户端套接字。

相关问题