No meu thread principal, tenho um while(listening)
loop que chama accept()
meu objeto ServerSocket, inicia um novo thread do cliente e o adiciona a uma coleção quando um novo cliente é aceito.
Também tenho um thread de administração que quero usar para emitir comandos, como 'exit', que fará com que todos os threads do cliente sejam desligados, desligados e desligados do thread principal, tornando a escuta false.
No entanto, a accept()
chamada no while(listening)
loop é bloqueada e não parece haver nenhuma maneira de interrompê-la, portanto a condição while não pode ser verificada novamente e o programa não pode sair!
Existe uma maneira melhor de fazer isso? Ou alguma maneira de interromper o método de bloqueio?
java
networking
blocking
interrupt
lukeo05
fonte
fonte
Respostas:
Você pode ligar
close()
de outro segmento, e aaccept()
chamada emitirá aSocketException
.fonte
close()
, quero dizer, isso lançará a exceção ao fazê-lo; portanto, existe outra maneira (que não gera exceção, também não baseada no tempo limite) para parar de atender a solicitações?readLine()
retornará nulo e ocorrerão as operações normais de fechamento que o encadeamento já deve ter.Ative o tempo limite
accept()
, a chamada atingirá o tempo limite do bloqueio após o tempo especificado:http://docs.oracle.com/javase/7/docs/api/java/net/SocketOptions.html#SO_TIMEOUT
fonte
Está chamando
close()
aServerSocket
uma opção?http://java.sun.com/j2se/6/docs/api/java/net/ServerSocket.html#close%28%29
fonte
Você pode simplesmente criar um soquete "void" para quebrar os servidores socket.accept ()
Lado do servidor
Método para interromper o ciclo do servidor
fonte
A razão
ServerSocket.close()
lança uma exceção é porque você tem umoutputstream
ou uminputstream
anexo a esse soquete. Você pode evitar essa exceção com segurança fechando primeiro os fluxos de entrada e saída. Em seguida, tente fechar oServerSocket
. Aqui está um exemplo:Você pode chamar esse método para fechar qualquer soquete de qualquer lugar sem obter uma exceção.
fonte
ServerSocket
mas ao a,Socket
e estamos falando de fechar oServerSocket
not theSocket
, para que eleServerSocket
possa ser fechado sem fecharSocket
os fluxos de a.Use serverSocket.setSoTimeout (timeoutInMillis) .
fonte
OK, consegui isso trabalhando de uma maneira que resolva a questão do OP mais diretamente.
Continue lendo a resposta curta para um exemplo de Thread de como eu uso isso.
Resposta curta:
Exemplo do mundo real:
Neste exemplo, eu tenho um ServerSocket aguardando uma conexão dentro de um Thread. Quando fecho o aplicativo, desejo desligar o encadeamento (mais especificamente, o soquete) de maneira limpa antes de deixá-lo fechar, então uso o .setSoTimeout () no ServerSocket e depois a interrupção acionada após o tempo limite para verificar e verificar se o pai está tentando desligar o encadeamento. Nesse caso, defino o soquete, defino um sinalizador indicando que o encadeamento está concluído e interrompo o loop do encadeamento, que retorna um valor nulo.
Então, na minha classe Controller ... (mostrarei apenas o código relevante, massageie-o no seu próprio código, conforme necessário)
Espero que isso ajude alguém no caminho.
fonte
Outra coisa que você pode tentar, que é mais limpa, é verificar um sinalizador no loop de aceitação e, quando o thread do administrador desejar eliminar o bloqueio de threads no accept, defina o sinalizador (torne o thread seguro) e faça um soquete de cliente ligação à tomada de audição. A aceitação interromperá o bloqueio e retornará o novo soquete. Você pode descobrir alguma coisa simples sobre o protocolo que diz ao thread de escuta para sair do thread de maneira limpa. E, em seguida, feche o soquete no lado do cliente. Sem exceções, muito mais limpo.
fonte