En mi hilo principal, tengo un while(listening)
bucle que invoca accept()
mi objeto ServerSocket, luego inicia un nuevo hilo de cliente y lo agrega a una Colección cuando se acepta un nuevo cliente.
También tengo un hilo de administración que quiero usar para emitir comandos, como 'salir', que hará que todos los hilos del cliente se apaguen, se apaguen y apaguen el hilo principal, haciendo que la escucha sea falsa.
Sin embargo, la accept()
llamada en el while(listening)
bucle se bloquea, y no parece haber ninguna forma de interrumpirla, por lo que la condición while no se puede verificar nuevamente y el programa no puede salir.
¿Hay una mejor manera de hacer esto? ¿O alguna forma de interrumpir el método de bloqueo?
java
networking
blocking
interrupt
lukeo05
fuente
fuente
Respuestas:
Puede llamar
close()
desde otro hilo, y laaccept()
llamada arrojará unSocketException
.fuente
close()
Quiero decir que arrojará la excepción al hacerlo, entonces, ¿hay alguna otra manera (que no arroje una excepción, tampoco basada en el tiempo de espera) para dejar de escuchar las solicitudes?readLine()
entonces regresará nulo y ocurrirán las operaciones de cierre normales que el hilo ya debería tener en su lugar.Configure el tiempo de espera activado
accept()
, luego la llamada expirará el bloqueo después del tiempo especificado:http://docs.oracle.com/javase/7/docs/api/java/net/SocketOptions.html#SO_TIMEOUT
fuente
¿Llamar
close()
aServerSocket
una opción?http://java.sun.com/j2se/6/docs/api/java/net/ServerSocket.html#close%28%29
fuente
Simplemente puede crear un socket "vacío" para romper serversocket.accept ()
Lado del servidor
Método para romper el ciclo del servidor
fuente
La razón
ServerSocket.close()
arroja una excepción es porque tiene unoutputstream
o uninputstream
adjunto a ese socket. Puede evitar esta excepción de forma segura cerrando primero los flujos de entrada y salida. Entonces intente cerrar elServerSocket
. Aquí hay un ejemplo:Puede llamar a este método para cerrar cualquier socket desde cualquier lugar sin obtener una excepción.
fuente
ServerSocket
pero aSocket
y estamos hablando de cerrar elServerSocket
no elSocket
, por lo queServerSocket
pueden cerrarse sin cerrarSocket
los flujos de a.Utilice serverSocket.setSoTimeout (timeoutInMillis) .
fuente
OK, conseguí que esto funcione de una manera que aborde la pregunta del OP más directamente.
Sigue leyendo más allá de la respuesta corta para ver un ejemplo de Thread sobre cómo uso esto.
Respuesta corta:
Ejemplo del mundo real:
En este ejemplo, tengo un ServerSocket esperando una conexión dentro de un Thread. Cuando cierro la aplicación, quiero cerrar el hilo (más específicamente, el zócalo) de manera limpia antes de dejar que la aplicación se cierre, así que uso el .setSoTimeout () en el ServerSocket y luego uso la interrupción que se produce después del tiempo de espera para verificar y ver si el padre está intentando cerrar el hilo. Si es así, configuro cerrar el zócalo, luego establezco un indicador que indica que el subproceso está hecho, luego salgo del bucle de subprocesos que devuelve un valor nulo.
Luego, en mi clase de controlador ... (solo mostraré el código relevante, masajee su propio código según sea necesario)
Espero que esto ayude a alguien en el camino.
fuente
Otra cosa que puede probar, que es más limpia, es verificar una bandera en el bucle de aceptación, y luego, cuando su hilo de administración quiera eliminar el bloqueo de hilo en la aceptación, configure la bandera (haga que sea seguro para el hilo) y luego haga un socket de cliente conexión a la toma de escucha. La aceptación dejará de bloquear y devolverá el nuevo socket. Puede resolver algo de protocolo simple que le dice al hilo de escucha que salga del hilo limpiamente. Y luego cierre el zócalo en el lado del cliente. Sin excepciones, mucho más limpio.
fuente