2011-11-01 72 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

我也可以證實這一點的工作!很好的方式來打破在數據報套接字的接收循環中的工作線程。 – Nerdtron

1

使用UDP,您可以從另一個線程向套接字發送一個數據報,以解除對read()的阻止。 datagran可以(取決於你的協議)包含'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,它是不確定的,通過將其更改爲正數,它將僅阻塞您指定的數量。 (請確保您調用socket.receive之前設置())

這裏是回答在這個網站的例子: set timeout for socket receive

相關問題