How to handle timeout in Async Socket?

﹥>﹥吖頭↗ 提交于 2019-11-26 21:38:12

问题


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. Some of the article in Internet suggest to use WaitOne, but this will blocks the thread and defers the purpose of using I/O completion.

What is the best way to handle timeout in async socket?

 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

回答1:


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.
     }
}


来源:https://stackoverflow.com/questions/5973342/how-to-handle-timeout-in-async-socket

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