我有一个类(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
}
}
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"方法,有时一切都按预期工作:
但出于某种原因,有时候,当我使用" SendData"方法,我有以下行为:
在第二种情况下,我不明白为什么DataReceived回调发生在DataSent回调之前(从1到10ms之前)。你能帮我解决这个问题吗?谢谢。