Пример #1
0
    //接收数据回调
    private void ReceiveCallBack(IAsyncResult ar)
    {
        try
        {
            int len = m_Client.EndReceive(ar);

            if (len > 0)//已经接收到数据
            {
                //把接收到的数据写入缓冲数据流的尾部
                m_ReceiveMS.Position = m_ReceiveMS.Length;

                //把长度的字节写入数据流
                m_ReceiveMS.Write(m_ReceiveBuffer, 0, len);

                //如果缓存数据流的长度大于2说明至少有个不完整的包传递过来,因为包头为ushort长度为2
                if (m_ReceiveMS.Length > 2)
                {
                    //进行循环拆分数据包
                    while (true)
                    {
                        //把数据流指针位置放在0处
                        m_ReceiveMS.Position = 0;

                        //currMsgLen =包体的长度
                        int currMsgLen = m_ReceiveMS.ReadUShort();

                        //总包的长度
                        int currFullMsgLen = 2 + currMsgLen;

                        if (m_ReceiveMS.Length >= currFullMsgLen)
                        {
                            //至少收到一个完整包
                            //定一包体的buffer
                            byte[] buffer = new byte[currMsgLen];

                            //把数据流指针位置放在包体处
                            m_ReceiveMS.Position = 2;

                            //把包体读到buffer中
                            m_ReceiveMS.Read(buffer, 0, currMsgLen);

                            //把数据压入队列
                            lock (m_ReceiveQueue)
                            {
                                m_ReceiveQueue.Enqueue(buffer);
                            }
                            //==========处理剩余字节数组=========

                            //剩余包长度
                            int remainLen = (int)m_ReceiveMS.Length - currFullMsgLen;
                            if (remainLen > 0)
                            {
                                //把指针放在第一个包的尾部
                                m_ReceiveMS.Position = currFullMsgLen;

                                //定义剩余字节数据组
                                byte[] remainBuffer = new byte[remainLen];

                                //把数据流得到剩余字节数组
                                m_ReceiveMS.Read(remainBuffer, 0, remainLen);

                                //请空数据流
                                m_ReceiveMS.Position = 0;
                                m_ReceiveMS.SetLength(0);

                                //把剩余字节数组重新写入数据流
                                m_ReceiveMS.Write(remainBuffer, 0, remainBuffer.Length);

                                remainBuffer = null;
                            }
                            else
                            {
                                //没有剩余字节
                                //请空数据流
                                m_ReceiveMS.Position = 0;
                                m_ReceiveMS.SetLength(0);
                                break;
                            }
                        }
                        else
                        {
                            //还没有收到完整包
                            break;
                        }
                    }
                }

                //进行下一次接收数据包
                ReceiveMsg();
            }
            else
            {
                //服务器断开连接
                Debug.Log(string.Format("服务器{0}断开连接", m_Client.RemoteEndPoint.ToString()));
            }
        }
        catch
        {
            //服务器断开连接
            Debug.Log(string.Format("服务器{0}断开连接", m_Client.RemoteEndPoint.ToString()));
        }
    }
Пример #2
0
    //==========================================================

    private void Update()
    {
        #region 从队列获取数据
        while (true)
        {
            if (m_ReceiveCount <= 5)
            {
                m_ReceiveCount++;
                lock (m_ReceiveQueue)
                {
                    if (m_ReceiveQueue.Count > 0)
                    {
                        //得到队列中的数据包
                        byte[] buffer = m_ReceiveQueue.Dequeue();
                        //得到加密后的数据
                        byte[] bufferNew = new byte[buffer.Length - 3];

                        bool   isCompress = false;
                        ushort crc        = 0;

                        using (ByteMemoryStream ms = new ByteMemoryStream(buffer))
                        {
                            isCompress = ms.ReadBool();
                            crc        = ms.ReadUShort();
                            ms.Read(bufferNew, 0, bufferNew.Length);
                        }

                        //先校验
                        int newCrc = Crc16.CalculateCrc16(bufferNew);
                        if (newCrc == crc)
                        {
                            //异或得到原始数据
                            bufferNew = SecurityUtil.Xor(bufferNew);

                            if (isCompress)
                            {
                                bufferNew = ZlibHelper.DeCompressBytes(bufferNew);
                            }

                            ushort protoCode    = 0;
                            byte[] ProtoContent = new byte[bufferNew.Length - 2];
                            //协议编号
                            using (ByteMemoryStream ms = new ByteMemoryStream(bufferNew))
                            {
                                protoCode = ms.ReadUShort();
                                ms.Read(ProtoContent, 0, ProtoContent.Length);
                                //获取数据需要派发出去
                                GameEntry.Event.Broadcast(protoCode, ProtoContent);
                            }
                        }
                        else
                        {
                            Debug.Log("校验出错,不予接受");
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
            else
            {
                m_ReceiveCount = 0;
                break;
            }
        }
        #endregion
    }