c# 异步socket 分包接收_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > c# 异步socket 分包接收

c# 异步socket 分包接收

 2013/7/29 17:09:24  Red Cat  博客园  我要评论(0)
  • 摘要:///<summary>///接受数据完成处理函数,异步的特性就体现在这个函数中,///收到数据后,会自动解析为字符串报文///</summary>///<paramname="iar">目标客户端Socket</param>protectedvirtualvoidReceiveData(IAsyncResultiar){//iar.AsyncStateSocketclient=(Socket)iar.AsyncState;try
  • 标签:C# 异步socket socket 异步
        /// <summary> 
        /// 接受数据完成处理函数,异步的特性就体现在这个函数中, 
        /// 收到数据后,会自动解析为字符串报文 
        /// </summary> 
        /// <param name="iar">目标客户端Socket</param> 
        protected virtual void ReceiveData(IAsyncResult iar)
        {
            //iar.AsyncState
            Socket client = (Socket)iar.AsyncState;
            try
            {
                //如果两次开始了异步的接收,所以当客户端退出的时候 
                //会两次执行EndReceive 
                int recv = client.EndReceive(iar);

                if (recv == 0)
                {
                    //正常的关闭 
                    CloseClient(client, Session.ExitType.NormalExit);
                    return;
                }
                if (RecvData != null)
                {
                    Session sendDataSession = FindSession(client);//查找客户端
                    Debug.Assert(sendDataSession != null);
                    if (sendDataSession.RecordSize == 0)
                    {
                        byte[] headSize = YH(_recvDataBuffer, 4);
                        uint copysize = BitConverter.ToUInt32(headSize, 0);
                        sendDataSession.DataMaxSize = copysize+4; //这里+4忽略是因为协议上 对方忘记计算了一个dword 所以我接受直接多接收就好了。
                        sendDataSession.DataG = null;
                    }
                    uint len = sendDataSession.DataMaxSize - (uint)sendDataSession.RecordSize;
                    if (len >= FenbaoSize)
                    {
                        //如果大于等于255 就直接读255 。
                        byte[] temp = new byte[255];
                        if (sendDataSession.RecordSize == 0)
                        {
                            sendDataSession.DataG = _recvDataBuffer.Take(FenbaoSize).ToArray();
                        }
                        else
                        {
                            sendDataSession.DataG = sendDataSession.DataG.Concat(_recvDataBuffer.Take(FenbaoSize).ToArray()).ToArray();
                        }
                        sendDataSession.RecordSize = sendDataSession.RecordSize + FenbaoSize;
                    }else
                    if (len<FenbaoSize)
                    {
                        //如果小于255 说明也是最后一个包了。
                        sendDataSession.RecordSize = sendDataSession.RecordSize + (int)len;
                        sendDataSession.DataG=sendDataSession.DataG.Concat(_recvDataBuffer.Take((int)len).ToArray()).ToArray();
                    }
                    if (sendDataSession.RecordSize == sendDataSession.DataMaxSize)//如果接收完毕。就拷贝过来,然后初始化 最后发布数据事件
                    {
                        ICloneable copySession = (ICloneable)sendDataSession;//拷贝
                        Session clientSession = (Session)copySession.Clone();
                        clientSession.DataG = sendDataSession.DataG;//给数据
                        sendDataSession.RecordSize = 0;//初始化
                        sendDataSession.DataMaxSize = 0;
                        RecvData(this, new NetEventArgs(clientSession));//发布收到数据的事件 
                    }
                }
                client.BeginReceive(_recvDataBuffer, 0, FenbaoSize, SocketFlags.None,
                    new AsyncCallback(ReceiveData), client);//继续监听

            }
            catch (SocketException ex)
            {
                //客户端退出 
                if (10054 == ex.ErrorCode)
                {
                    //客户端强制关闭 
                    CloseClient(client, Session.ExitType.ExceptionExit);
                }
            }
            catch (ObjectDisposedException ex)
            {
                if (ex != null)
                {
                    ex = null;
                    //DoNothing; 
                }
            }
        }

貌似异步必须分包接收?不然有粘包现象? 不知道反正我是这么改的。 如果有学习soket的可以一起交流啊。我很菜~

发表评论
用户名: 匿名