使用SocketAsyncEventArgs犯的低级错误
之前在使用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(); } }
访问Beetlex的Github