2011-11-01 4 views
9

creo un DatagramSocket en el hilo principal, y luego creo un hilo de clase interno para escuchar el puerto. cuando cierro el DatagramSocket en el hilo principal, siempre me encontré con un error socket closed porque en el hilo de la clase interna llamé al método , y bloqueó el hilo de la clase interna. aquí está el código de la clase interna:cómo puedo detener el método de bloque DatagramSocket.receive() en un hilo

class ReceiveText extends Thread 
{ 
    @Override 
    public void run() 
    { 
     while(true) 
     { 
      byte[] buffer = new byte[1024]; 
      DatagramPacket dp = new DatagramPacket(buffer, buffer.length); 
      try { 
       udpSocket.receive(dp);//blocked here 
       byte[] data = dp.getData(); 
       String message = new String(data, 0 , dp.getLength()); 
       setTxtAreaShowMessage(message); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

quiero detener el hilo de clase interna antes del cierre del DatagramSocket, pero no se recomienda el método stop(). ¿Cómo puedo hacer eso?

Respuesta

13

Cierre el socket, lo que detendrá la llamada a receive() de bloqueo. Si primero establece un indicador cerrado, entonces en el bloque catch (IOException) puede ignorar la excepción de forma segura si se establece el indicador. (Probablemente también podría usar el método isClosed() en DatagramSocket en lugar de un indicador)

+0

que es una solución, gracias – cloud

+0

También puedo confirmar esto funciona! Una buena manera de salir de un hilo de trabajo que está en un bucle de recepción en un socket de datagrama. – Nerdtron

1

Con UDP, puede enviar el socket a un datagrama de otro hilo, por lo que se desbloquea la lectura(). El granista de datos podría, (según su protocolo), contener un comando 'suicidio' o podría usar un booleano 'apagado' adicional que el hilo lea después de que read() retorne.

2

Socket.close() hace el truco. O puede usar socket.setSoTimeout (1000); el método setSoTimeout() le permite definir un período de tiempo de espera en milisegundos. Por ejemplo:

//if the socket does not receive anything in 1 second, 
//it will timeout and throw a SocketTimeoutException 
//you can catch the exception if you need to log, or you can ignore it 
socket.setSoTimeout(1000); 
socket.receive(); 

Aquí está el javadoc for setSoTimeout();

De manera predeterminada, el tiempo de espera es 0, que es indefinido, al cambiarlo a un número positivo, solo se bloqueará por la cantidad especificada. (Asegúrese de configurar antes de llamar socket.receive())

Este es un ejemplo contestado en este sitio: set timeout for socket receive

Cuestiones relacionadas