Пример #1
0
        void EndReceiveFromCallback(IAsyncResult iar)
        {
            SocketState state  = iar.AsyncState as SocketState;
            Socket      socket = state.Socket;

            try
            {
                int byteRead = socket.EndReceiveFrom(iar, ref state.RemoteEP);
                MyCentorl.RecvMessage(state.Buffer);
            }
            catch (Exception e)
            {
                Console.WriteLine("发生异常!异常信息:");
                Console.WriteLine(e.Message);
            }
            finally
            {
                //非常重要:继续异步接收
                socket.BeginReceiveFrom(
                    state.Buffer, 0, state.Buffer.Length,
                    SocketFlags.None,
                    ref state.RemoteEP,
                    EndReceiveFromCallback,
                    state);
            }
        }
Пример #2
0
        private void OnRecv(IAsyncResult ar)
        {
            try
            {
                int    recvLength = socket.EndReceive(ar);
                int    pkgLength  = 0;
                byte[] data;
                //如果半包数据不为空
                if (null != backupBuffer)
                {
                    //将半包和后面接收到的数据报拼接起来
                    data = backupBuffer.Concat(recvBuffer.Take(recvLength).ToArray()).ToArray();
                }
                else
                {
                    data = recvBuffer.Take(recvLength).ToArray();
                }
                //解决连包问题
                while (true)
                {
                    // 1. recvEvent返回一个完整的数据包长度
                    pkgLength = MyCentorl.RecvMessage(data);

                    if (pkgLength <= 0 || pkgLength > maxPackage)
                    {
                        //出现异常,连接关闭
                        state = ServiceModel.BASESOCKET_STATE.SOCKET_ERROR;
                        Close();
                        break;
                    }

                    // 2. 如果正常处理完,则直接启动下次接收
                    if (pkgLength == data.Length)
                    {
                        ////TraceUtil.Log("正常");
                        backupBuffer = null;
                        Array.Clear(recvBuffer, 0, recvBuffer.Length);
                        pkgLength = 0;
                        break;
                    }
                    // 3. 如果还未接收完,半包则在偏移处等待
                    else if (pkgLength > data.Length)
                    {
                        //将半包数据拷贝到backupBuffer
                        ////TraceUtil.Log("半包");
                        backupBuffer = data.Take(data.Length).ToArray();
                        break;
                    }
                    // 4. 如果是连包,则循环处理
                    else if (pkgLength < data.Length)
                    {
                        //自增偏移量并跳过已经处理的包
                        ////TraceUtil.Log("连包");
                        data         = data.Skip(pkgLength).ToArray();
                        backupBuffer = null;
                    }
                    else
                    {
                        break;
                    }
                }
                StartRecv();
            }
            catch
            {
                state = ServiceModel.BASESOCKET_STATE.SOCKET_ERROR;
                Close();
            }
        }