Example #1
0
    /// <summary>
    /// 封装数据包。
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    private byte[] makeData(byte[] data)
    {
        bool isCompress = false;

        if (data.Length > 200)
        {
            isCompress = true;
            data       = ZlibHelper.CompressBytes(data);
        }
        data = SecurityUtil.Xor(data);               //加密
        ushort crc     = Crc16.CalculateCrc16(data); //校验码。
        ushort bodyLen = (ushort)(data.Length + 3);  //包体长度

        MyMemoryStream m = new MyMemoryStream();

        m.WriteUShort(bodyLen);
        m.WriteBool(isCompress);
        m.WriteUShort(crc);
        m.Write(data, 0, data.Length);
        data = m.ToArray();
        m.Close();

        return(data);
    }
Example #2
0
    private void receiveCallback(IAsyncResult ar)
    {
        int len = 0;

        try
        {
            len = this.socket.EndReceive(ar);  //len为真实的收到的字节数
        }
        catch (Exception)
        {
            Debug.Log("链接断了。");
        }

        if (len > 0)
        {
            byte[] tmp = new byte[len];
            Buffer.BlockCopy(this.buffer, 0, tmp, 0, len);

            //每次收到数据,把数据写入流末尾
            myReceiveBuffer.Position = myReceiveBuffer.Length; ///流里的读写的起始位置,设定到流的末尾
            myReceiveBuffer.Write(tmp, 0, tmp.Length);         //把新收到的数据追加到流的末尾。

            ///处理粘包的循环
            while (true)
            {
                //1.从流的开头读取包体长度
                myReceiveBuffer.Position = 0;
                ushort bodyLen = myReceiveBuffer.ReadUshort();
                ushort fullLen = (ushort)(bodyLen + 2);
                if (myReceiveBuffer.Length >= fullLen) //说明够一个完整的包了。
                {
                    myReceiveBuffer.Position = 2;      //从是否压缩的标识的位置开始读取标识。
                    bool   isCompress = myReceiveBuffer.ReadBool();
                    ushort crc        = myReceiveBuffer.ReadUshort();
                    //读取数据部分
                    byte[] data = new byte[bodyLen - 3];
                    myReceiveBuffer.Read(data, 0, data.Length);

                    //////以上是 ,该读取的都读取出来了。。。
                    ushort newCrc = Crc16.CalculateCrc16(data);
                    if (newCrc == crc)                 //校验通过。
                    {
                        data = SecurityUtil.Xor(data); //解密
                        if (isCompress)                //如果是经过压缩的,解个压缩。
                        {
                            data = ZlibHelper.DeCompressBytes(data);
                        }
                        ///把接出来的数据包放入队列。主线程中再处理数据。
                        msgQueue.Enqueue(data);///放入队列等待主线程处理。
                    }

                    ///剩余数据在容器中保留,刚处理完的,删除。
                    ushort remainLen = (ushort)(myReceiveBuffer.Length - fullLen);
                    if (remainLen > 0)
                    {
                        byte[] remainArr = new byte[remainLen];
                        myReceiveBuffer.Position = fullLen;
                        myReceiveBuffer.Read(remainArr, 0, remainArr.Length);

                        ///清楚容器(myReceiveBuffer)里的所有内容
                        myReceiveBuffer.SetLength(0);
                        myReceiveBuffer.Position = 0;

                        //剩余部分再写回来
                        myReceiveBuffer.Write(remainArr, 0, remainArr.Length);
                    }
                    else
                    {
                        ///剩余部分长度为 0,,清楚容器(myReceiveBuffer)里的所有内容
                        myReceiveBuffer.SetLength(0);
                        myReceiveBuffer.Position = 0;
                        break;
                    }
                }
                else
                {
                    break;
                }
            }

            ///再次收下次的数据,否则只能收取一次数据。
            this.socket.BeginReceive(this.buffer, 0, buffer.Length, SocketFlags.None, receiveCallback, null);
        }
        else  //len==0链接断了
        {
            Debug.Log("链接断了。");
        }
    }