How to handle timeout in Async Socket?

守給你的承諾、 提交于 2019-11-28 01:10:41

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.
     }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!