Olá galera,
Bom estou com um problema, já descobri a causa e até implementei uma solução, mas não me pareceu a melhor, por isso conta coma ajuda
do pessoal mais experiente. o Código é mais ou menos esse:
Tenho essa Thread que funciona como um servidor
public class Server extends Thread {
private ServerSocket serverSocket;
private boolean executar = true;
public Server() throws IOException {
this.serverSocket = new ServerSocket(5454);
}
@Override
public void run() {
while (executar) {
try {
Socket socket = serverSocket.accept();
//trata conexão
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public void terminar() {
this.executar = false;
if (!serverSocket.isClosed()) {
try {
this.serverSocket.close();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, "Não foi possível finalizar o Server", ex);
}
}
}
O problema é o seguinte, quando inicio essa Thread, ela fica parada no método server.accept(), por que ele é blocante, porém se neste momento eu chamar
o método terminar, e a execução da Thread estiver parada no accept(), ocorre o erro:
java.net.SocketException: socket closed
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:390)
at java.net.ServerSocket.implAccept(ServerSocket.java:462)
at java.net.ServerSocket.accept(ServerSocket.java:430)
at testesocket.Server.run(Main.java:60)
isso porque o ServerSocket foi fechado e ainda tentou aceitar lançando o erro. Eu até consegui um jeito que funcionou mas acho que pode existir outro melhor, no caso minha solução foi a seguinte, no método terminar, antes de dar um close, eu crio um socket local para conectar com o server, liberando-o da linha accept.
new Socket("127.0.0.1",5454);
this.serverSocket.close();
O código é mais ou menos assim, na verdade é um sistema de chat da empresa, que não seria legal colocar o código aqui, mas a lógica é a mesma. Imaginem que esse método terminar é a ação para ficar offline, e este server socket é um console de atendimento esperando conexões.
O que eu queria saber, é se tem alguma forma de antes de dar o close, eu fazer com que o serverSocket saia da linha de accept para que eu possa fecha-lo sem dar esse erro?