Java: properly closing sockets for multi threaded servers

為{幸葍}努か 提交于 2021-02-16 18:06:33

问题


I'm trying to create a multi threaded server to which multiple clients can connect and can be served. However, I'm not sure on how to properly free up my resources should the need arise.

My server runs an input thread (waiting for user inputs) and a procressing thread (handles connections and users). I open up a ServerSocket in the server class and pass it to my processing thread. It looks like this:

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);
        }           
    }   
}
}

If I want to exit, I just run this method in my server class to close the ServerSocket:

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

Which should cause the next serverSocket.accept() call to throw an exception, and the loop stops since the socket is closed.

My question is - 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?


回答1:


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

No, it has no effect on them.

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

Yes, and you should be doing that anyway, in every handler thread.

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

Just impose a read timeout and close each socket that times out. This is a normal part of any server. You don't have to collect the sockets or take any special measures about them for shutdown.




回答2:


No, it doesn't. It just closes the ServerSocket meaning new connections can't be made. The existing open sockets will still keep working.

There's no "easy" way to close all the open sockets because it's not really hard to begin with (or if you find that as a hard part in network programming, there's something very strange going on).




回答3:


Let the client handler thread, closes the client socket on the end of processing.



来源:https://stackoverflow.com/questions/40574796/java-properly-closing-sockets-for-multi-threaded-servers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!