Я пытаюсь создать многопоточный сервер, к которому могут подключаться несколько клиентов. Однако я не уверен, как правильно освободить свои ресурсы, если возникнет такая необходимость.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, которые были созданы с его помощью? Или я должен обязательно закрыть каждый открытый клиентский ключ вручную? Если да, есть ли простой способ сделать это, а не сохранять каждое соединение, сделанное на сервере где-нибудь?
Проблема заключается в том, что любые сокеты, которые открываются в то время, когда мы закрываем сокет сервера, открыты, потому что они заблокированы, ожидая ввода от клиента. И их странный вид блокировки, который нельзя даже прервать. Даже трюк отправки пустого пакета для разблокировки сокета не работает, потому что они ждут уже установленных соединений с третьими лицами, вы не можете вставлять пустой пакет в эти соединения. Итак, вы нашли решение? –