之前在使用SocketAsyncEventArgs進行數據接收的時候,經常發現某部分數據錯亂但確沒有影響協議分析。在無意中發現原來犯了個低級錯誤,先看下以下代碼:
public void IO_ReceiveComplete(TcpSocketAsyncEventArgs e)
{
TcpChannel channel = e.Channel;
if (e.BytesTransferred > 0 && e.SocketError == System.Net.Sockets.SocketError.Success)
{
lock (TcpUtils.mLockReceiveDataLength)
{
TcpUtils.ReceiveDataLength += e.BytesTransferred;
}
channel.BeginReceive();
ReceiveItem item = new ReceiveItem();
item.SocketAsyncEventArgs = e;
item.Channel = channel;
channel.ReceiveDespatch.Add(item);
}
else
{
e.Enter();
channel.Dispose();
}
}
以上代碼看上去似乎沒有什么問題,在接收數據后進行下一次接收然后把當前接收的數據放到隊列中處理.不過好像忘了一個事情就是SocketAsyncEventArgs在接收數據的時候有可能存在同步完成,如果真是同步完成那結果是怎樣呢。自然就是后面的數據會先添加到隊列中,而前面的數據添加在后面,但由於同步完成是不確定性的,所以就出現有時正常,有時數據錯亂
..把代碼改成先放隊列再進行下一下收接就行了
public void IO_ReceiveComplete(TcpSocketAsyncEventArgs e)
{
TcpChannel channel = e.Channel;
if (e.BytesTransferred > 0 && e.SocketError == System.Net.Sockets.SocketError.Success)
{
lock (TcpUtils.mLockReceiveDataLength)
{
TcpUtils.ReceiveDataLength += e.BytesTransferred;
}
ReceiveItem item = new ReceiveItem();
item.SocketAsyncEventArgs = e;
item.Channel = channel;
channel.ReceiveDespatch.Add(item);
channel.BeginReceive();
}
else
{
e.Enter();
channel.Dispose();
}
}
