C#异步套接字已发送和已接收回调

时间:2015-08-19 09:43:18

标签: c# sockets asynchronous callback

我有一个类(AsyncClient),它能够使用TCP / IP套接字发送和接收数据。此类使用异步套接字方法,以便更好地处理错误并避免线程。

以下是我的代码的简化版本:

连接方法

    private Socket _socket;
    private byte[] _receivedDataBuffer;
    private byte[] _sentDataBuffer;

    public void Connect(IPEndPoint serverEndPoint)
    {
        try
        {
            //Create the socket object
            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            _socket.Blocking = false;

            //Connect to server
            _socket.BeginConnect(serverEndPoint, new AsyncCallback(OnConnected), _socket);
        }
        catch(Exception)
        {
             //Handle error
        }
    }

    private void OnConnected(IAsyncResult Result)
    {
        //Socket was the passed in object
        Socket socket = (Socket)Result.AsyncState;

        try
        {
            socket.EndConnect(Result);
            if (socket.Connected) //Check if we were sucessfull
            {
                //Setup receive callback
                _receivedDataBuffer = new byte[socket.ReceiveBufferSize];
                socket.BeginReceive(_receivedDataBuffer, 0, _receivedDataBuffer.Length, SocketFlags.None, new AsyncCallback(OnDataReceived), socket);

                //Raise "Connected" event on UI thread
            }
            else
            {
                //Handle error
            }
        }
        catch (Exception E)
        {
             //Handle error
        }
    }

数据收到回叫

    private void OnDataReceived(IAsyncResult Result)
    {
        //Sometimes, this occurs before the DataSent callback
        Console.WriteLine("Received: " + DateTime.Now.ToString("hh.mm.ss.fff"));

        //Socket was the passed in object
        Socket socket = (Socket)Result.AsyncState;

        try
        {
            int received = socket.EndReceive(Result);
            if (received > 0)
            {
                //Store received data

                //Raise "DataReceived" event on UI thread

                //Restablish the callback
                socket.BeginReceive(_receivedDataBuffer, 0, _receivedDataBuffer.Length, SocketFlags.None, new AsyncCallback(OnDataReceived), socket);
            }
            else
            {
                //Handle error
            }
        }
        catch (Exception E)
        {
             //Handle error
        }
    }

发送方法和DataSent回调

    public void SendData(byte[] Data)
    {
        _sentDataBuffer = Data;
        _socket.BeginSend(_sentDataBuffer, 0, _sentDataBuffer.Length, SocketFlags.None, new AsyncCallback(OnDataSent), _socket);
    }

    private void OnDataSent(IAsyncResult Result)
    {
        //Sometimes, this occurs after the DataReceived callback
        Console.WriteLine("Sent: " + DateTime.Now.ToString("hh.mm.ss.fff")); 

        //Socket was the passed in object
        Socket socket = (Socket)Result.AsyncState;

        try
        {
            int sent = socket.EndSend(Result);
            if(sent > 0)
            {
                //Raise "DataSent" event on UI thread
            }
            else
            {
                //Handle error
            }
        }
        catch(Exception E)
        {
            //Handle error
        }
    }
}

我的问题

我使用此类将数据发送到服务器,该服务器几乎立即回答 。 因此,当我使用" SendData"方法,有时一切都按预期工作:

  1. 我发送的数据由远程服务器
  2. 接收
  3. 然后执行DataSent回调
  4. 远程服务器发回确认
  5. 然后执行获取ACK的DataReceived回调
  6. 但出于某种原因,有时候,当我使用" SendData"方法,我有以下行为:

    1. 我发送的数据由远程服务器
    2. 接收
    3. 远程服务器发回确认
    4. 然后执行获取ACK的DataReceived回调
    5. 然后执行DataSent回调
    6. 在第二种情况下,我不明白为什么DataReceived回调发生在DataSent回调之前(从1到10ms之前)。你能帮我解决这个问题吗?谢谢。

0 个答案:

没有答案