Interromper um soquete de conexão

Eu tenho uma GUI com uma lista de servidores para se conectar. Se um usuário clicar em um servidor, ele se conectará a ele. Se um usuário clicar em um segundo servidor, ele desconectará o primeiro e se conectará ao segundo. Cada nova conexão é executada em um novo encadeamento para que o programa possa executar outras tarefas.

No entanto, se um usuário clicar em um segundo servidor enquanto o primeiro ainda estiver se conectando, haverá duas conexões simultâneas.

Estou conectando usando isso, e connect () é a linha que bloqueia:

Socket socket = new Socket(); socket.connect(socketAddress, connectTimeout); 

Eu pensei que talvez Thread.currentThread().interrupt(); funcionaria, mas não funcionou.

Tenho que reestruturar um pouco o meu código para que ele continue fazendo a primeira conexão, mas feche logo depois? Ou existe realmente uma maneira de interromper o método de conexão.

Se você estiver usando uma implementação de soquete de bloqueio, interromper o segmento não cancelará nem interromperá sua conexão de soquete. A única maneira de sair da ‘chamada de bloqueio’ é ‘fechar’ o socket. Você pode expor um método em suas tarefas Runnable (por exemplo, cancel ) que fecha o soquete e limpa os resources quando o usuário tenta se conectar a um segundo servidor.

Se você quiser, pode dar uma olhada na minha tentativa de interromper os threads que fazem chamadas de bloqueio.

Você pode, em vez disso, usar um soquete sem bloqueio? Eu não sou muito de um especialista em Java, mas parece que o SocketChannel é sua class de socket sem bloqueio.

Aqui está um exemplo:

 // Create a non-blocking socket and check for connections try { // Create a non-blocking socket channel on port 80 SocketChannel sChannel = createSocketChannel("hostname.com", 80); // Before the socket is usable, the connection must be completed // by calling finishConnect(), which is non-blocking while (!sChannel.finishConnect()) { // Do something else } // Socket channel is now ready to use } catch (IOException e) { } 

Extraído daqui: http://www.exampledepot.com/egs/java.nio/NbClientSocket.html

Dentro do loop while você pode verificar se há alguma notificação compartilhada de que você precisa ser cancelado e sair, fechando o SocketChannel durante o processo.

Eu tentei as respostas sugeridas, mas nada funcionou para mim. Então, o que eu fiz foi, em vez de definir o tempo limite de conexão para 10 segundos, tentei conectar 5 vezes seguidas com um tempo limite de conexão de 2 segundos. Eu também tenho uma variável global boolean cancelConnection declarada.

Toda vez que uma exceção timeout é lançada, posso cancelar o loop ou continuar o loop com base no valor de cancelConnection .

Aqui está um trecho de código de um aplicativo Android que estou escrevendo:

 try { SocketAddress socketaddres = new InetSocketAddress(server.ip,server.port); int max=5; for (int i = 1; i<=max; i++) { try { socket = new Socket(); socket.connect(socketaddres, 2000); break; } catch (Exception e) { Log.d(TAG, "attempt "+i+ " failed"); if (cancelConnection) { Log.d(TAG, "cancelling connection"); throw new Exception(); } else if (i==max) { throw new Exception(); } } } } catch (Exception e) { if (cancelConnection) { // Do whatever you would do after connection was canceled. } else { // Do whatever you would do after connection error or timeout } }