How to handle timeout in Async Socket?

后端 未结 1 653
名媛妹妹
名媛妹妹 2020-12-06 13:22

I have a code that using async socket to send message to client and expecting response from it. If the client did not reply in a specified internal it will considers timeout

相关标签:
1条回答
  • 2020-12-06 13:48

    You can’t timeout or cancel asynchronous Socket operations.

    All you can do is start your own Timer which closes the Socket—the callback will then be immediately called and the EndX function will come back with an ObjectDisposedException if you call it. Here's an example:

    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.
         }
    }
    
    0 讨论(0)
提交回复
热议问题