2011-05-12 81 views
6

我有一個代碼,使用異步套接字發送消息給客戶端,並期待從它的響應。如果客戶沒有在指定的內部回覆,它會認爲超時。 Internet上的一些文章建議使用WaitOne,但這會阻塞該線程並推遲使用I/O完成的目的。如何處理異步套接字中的超時?

處理異步套接字超時的最佳方式是什麼?

Sub OnSend(ByVal ar As IAsyncResult) 
     Dim socket As Socket = CType(ar.AsyncState ,Socket) 
     socket.EndSend(ar) 

     socket.BeginReceive(Me.ReceiveBuffer, 0, Me.ReceiveBuffer.Length, SocketFlags.None, New AsyncCallback(AddressOf OnReceive), socket) 

End Sub 

回答

6

您不能超時或取消異步Socket操作。

所有你能做的就是開始自己Timer其封閉Socket -the回調將被立即調用,EndX功能會回來與ObjectDisposedException如果你調用它。以下是一個示例:

using System; 
using System.Threading; 
using System.Net.Sockets; 

class AsyncClass 
{ 
    Socket sock; 
    Timer timer; 
    byte[] buffer; 
    int timeoutflag; 

    public AsyncClass() 
    { 
      sock = new Socket(AddressFamily.InterNetwork, 
       SocketType.Stream, 
       ProtocolType.Tcp); 

      buffer = new byte[256]; 
    } 

    public void StartReceive() 
    { 
      IAsyncResult res = sock.BeginReceive(buffer, 0, buffer.Length, 
       SocketFlags.None, OnReceive, null); 

      if(!res.IsCompleted) 
      { 
       timer = new Timer(OnTimer, null, 1000, Timeout.Infinite); 
      } 
    } 

    void OnReceive(IAsyncResult res) 
    { 
      if(Interlocked.CompareExchange(ref timeoutflag, 1, 0) != 0) 
      { 
       // the flag was set elsewhere, so return immediately. 
       return; 
      } 

      // we set the flag to 1, indicating it was completed. 

      if(timer != null) 
      { 
       // stop the timer from firing. 
       timer.Dispose(); 
      } 

      // process the read. 

      int len = sock.EndReceive(res); 
    } 

    void OnTimer(object obj) 
    { 
      if(Interlocked.CompareExchange(ref timeoutflag, 2, 0) != 0) 
      { 
       // the flag was set elsewhere, so return immediately. 
       return; 
      } 

      // we set the flag to 2, indicating a timeout was hit. 

      timer.Dispose(); 
      sock.Close(); // closing the Socket cancels the async operation. 
    } 
} 
+1

我找到了類似的答案。 http://stackoverflow.com/questions/1231816/net-async-socket-timeout-check-thread-safety。 這個想法是有一個單一的定時器來照顧所有現有的連接來檢查它是否超時。 – kevin 2011-05-13 01:38:37