2011-05-12 48 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