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

时间:2016-11-13 14:15:05

标签: java sockets tcp distributed-system

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

我的服务器运行一个输入线程(等待用户输入)和一个应急线程(处理连接和用户)。我在服务器类中打开一个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?如果是这样,有没有一种简单的方法可以这样做,而不是保存在服务器上的每一个连接?

3 个答案:

答案 0 :(得分:0)

不,它没有。它只是关闭ServerSocket意味着无法建立新的连接。现有的开放式插座仍然可以继续工作。

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

答案 1 :(得分:0)

  

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

不,它对他们没有影响。

  

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

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

  

如果是这样,有没有一种简单的方法可以这样做,而不是保存在服务器上的每一个连接?

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

答案 2 :(得分:0)

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