zoukankan      html  css  js  c++  java
  • 使用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在接收数据的时候有可能存在同步完成,如果真是同步完成那结果是怎样呢。自然就是后面的数据会先添加到队列中,而前面的数据添加在后面,但由于同步完成是不确定性的,所以就出现有时正常,有时数据错乱Embarassed..把代码改成先放队列再进行下一下收接就行了

    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
  • 相关阅读:
    人生,时间煮雨,岁月缝花
    Nginx入门到实践---nginx中间件
    CentOS 8 系统安装 Oracle 19c 数据库
    centos8 下安装Oracle jdk8(免安装版)
    Mysql忘记密码
    这个病秋季高发!调理不当最伤孩子体质,记得收好这2个方
    redis client-output-buffer-limit 设置
    redis主从同步收到以下参数影响
    linux:永久打开core文件功能
    linux:core文件的产生和调试
  • 原文地址:https://www.cnblogs.com/smark/p/2343412.html
Copyright © 2011-2022 走看看