Java:正确关闭多线程服务器的套接字

Java: properly closing sockets for multi threaded servers

我正在尝试创建一个多线程服务器,多个客户端可以连接到该服务器并为其提供服务。但是,我不确定在需要时如何正确释放我的资源。

我的服务器运行有一个输入线程(等待用户输入)和一个处理线程(处理连接和用户)。我在服务器 class 中打开一个 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);
        }           
    }   
}
}

如果我想退出,我只需运行我的服务器class中的这个方法来关闭ServerSocket:

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

这应该会导致下一个 serverSocket.accept() 调用抛出异常,并且由于套接字关闭,循环停止。

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

does closing a ServerSocket implicitly close ClientSockets that were created using it?

不,对他们没有影响。

Or should I make sure to close every single open ClientSocket by hand?

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

If so, is there an easy way to do so instead of saving every single connection made to the server somewhere?

只需施加读取超时并关闭每个超时的套接字。这是任何服务器的正常部分。您无需收集套接字或对其采取任何特殊措施即可关闭。

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