2011-11-01 8 views
9

私はDatagramSocketをメインスレッドに作成し、内部クラススレッドを作成してポートをリッスンします。メインスレッドのDatagramSocketを閉じると、エラーsocket closedが発生しました。内部クラスのスレッドでは、というメソッドが呼び出され、内部クラスのスレッドがブロックされたためです。ここでは内部クラスのコードは次のとおりです。スレッド内のブロックメソッドDatagramSocket.receive()を停止するには

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(); 
      } 
     } 
    } 
} 

私は近いDatagramSocketの前に内部クラスのスレッドを停止したいのですが、stop()方法が推奨されていません。どうやってやるの?

答えて

13

ソケットを閉じると、receive()呼び出しがブロックされなくなります。最初にクローズド・フラグを設定した場合、catch(IOException)ブロックでは、フラグが設定されていれば安全に無視できます。 (おそらく、フラグの代わりにDatagramSocketのisClosed()メソッドを使用することもできます)。

+0

、感謝 – cloud

+0

私もこの作品を確認することができます(あなたがsocket.receiveを呼び出す前に設定していることを確認します())ここで

このサイトで答えた例があります!データグラムソケットの受信ループにあるワーカースレッドから抜け出す方法 – Nerdtron

1

UDPでは、ソケットを別のスレッドから送信してread()をブロック解除できます。データグランは(あなたのプロトコルに応じて) '自殺(suicide)'コマンドを含んでいても、read()が返った後にスレッドが読み取る追加の 'shutdown'ブール値を使うことができます。

2

Socket.close()はトリックを行います。または、socket.setSoTimeout(1000)を使用できます。 setSoTimeout()メソッドを使用すると、タイムアウト期間をミリ秒単位で定義できます。例:

//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(); 

ここにはjavadoc for setSoTimeout()があります。

デフォルトでは、タイムアウトは0です。これは不定で、正の数に変更すると指定した時間だけブロックされます。 ソリューションですset timeout for socket receive