예제 #1
0
        /// <summary>
        /// 尝试将收到的网络包解析为实体
        /// </summary>
        /// <param name="pack">收到的网络包</param>
        /// <returns></returns>
        /// <remarks>如果收到的包是分片包,且其所有子包尚未接受完全,则会返回空值</remarks>
        public static Msg TryToTranslateMessage(PacketNetWorkMsg pack)
        {
            if (pack == null || pack.PackageIndex > pack.PackageCount - 1)
            {
                return(null);
            }
            else if (pack.PackageCount == 1)
            {
                return(ParseToMessage(pack));
            }
            else
            {
                lock (packageCache)
                {
                    if (packageCache.ContainsKey(pack.PackageNo))
                    {
                        PacketNetWorkMsg[] array = packageCache[pack.PackageNo];
                        array[pack.PackageIndex] = pack;

                        //检测是否完整
                        if (Array.FindIndex(array, s => s == null) == -1)
                        {
                            packageCache.Remove(pack.PackageNo);
                            return(ParseToMessage(array));
                        }
                        else
                        {
                            return(null);
                        }
                    }
                    else
                    {
                        PacketNetWorkMsg[] array = new PacketNetWorkMsg[pack.PackageCount];
                        array[pack.PackageIndex] = pack;
                        packageCache.Add(pack.PackageNo, array);
                        return(null);
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// 将网络信息解析为封包
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public static PacketNetWorkMsg Parse(byte[] buffer, IPEndPoint clientAddress)
        {
            if (!Test(buffer))
            {
                return(null);
            }

            PacketNetWorkMsg p = new PacketNetWorkMsg()
            {
                RemoteIP  = clientAddress,
                SendTimes = 0
            };

            p.PackageNo             = BitConverter.ToInt64(buffer, 1);      //包编号
            p.DataLength            = (int)BitConverter.ToInt64(buffer, 9); //内容长度
            p.PackageCount          = BitConverter.ToInt32(buffer, 13);     //分包总数
            p.PackageIndex          = BitConverter.ToInt32(buffer, 17);     //索引
            p.IsRequireReceiveCheck = buffer[21] == 1;                      //是否需要回包
            p.Data = new byte[buffer.Length - PackageHeaderLength];
            Array.Copy(buffer, PackageHeaderLength, p.Data, 0, p.Data.Length);

            return(p);
        }
예제 #3
0
        /// <summary>
        /// 获得消息包的字节流
        /// </summary>
        /// <param name="remoteIp">远程主机地址</param>
        /// <param name="packageNo">包编号</param>
        /// <param name="command">命令</param>
        /// <param name="options">参数</param>
        /// <param name="userName">用户名</param>
        /// <param name="hostName">主机名</param>
        /// <param name="content">正文消息</param>
        /// <param name="extendContents">扩展消息</param>
        /// <returns></returns>
        public static PacketNetWorkMsg[] BuildNetworkMessage(IPEndPoint remoteIp, long packageNo, Commands command, string userName, string hostName, Consts type, byte[] content, byte[] extendContents, bool RequireReceiveCheck)
        {
            //每次发送所能容下的数据量
            int maxBytesPerPackage = (int)Consts.MAX_UDP_PACKAGE_LENGTH - PackageHeaderLength;
            //压缩数据流
            var ms = new MemoryStream();
            //var dest = new MemoryStream();
            //var zip = new GZipStream(dest, CompressionMode.Compress);
            var bw = new BinaryWriter(ms, System.Text.Encoding.Unicode);

            //写入头部数据
            bw.Write(packageNo);                            //包编号
            bw.Write(userName);                             //用户名
            bw.Write(hostName);                             //主机名
            bw.Write((long)command);                        //命令
            bw.Write((long)type);                           //数据类型
            bw.Write(content == null ? 0 : content.Length); //数据长度

            //写入消息数据
            if (content != null)
            {
                bw.Write(content);
            }
            bw.Write(extendContents == null ? 0 : extendContents.Length);//补充数据长度
            if (extendContents != null)
            {
                bw.Write(extendContents);
            }


            ms.Flush();
            ms.Seek(0, System.IO.SeekOrigin.Begin);
            byte[] ibuf = ms.ToArray();

            var        dest      = new System.IO.MemoryStream();
            GZipStream zipStream = new GZipStream(dest, CompressionMode.Compress, true);

            byte[] buff = new byte[1024];
            int    offset;

            ms.Seek(0, SeekOrigin.Begin);
            while ((offset = ms.Read(buff, 0, buff.Length)) > 0)
            {
                zipStream.Write(buff, 0, offset);//先把数据用二进制写入内存,然后在把它用zip压缩,获取压缩过后的二进制流dest
            }
            zipStream.Close();
            bw.Close();
            ms.Close();
            dest.Seek(0, SeekOrigin.Begin);
            //打包数据总量
            int dataLength = (int)dest.Length;

            int packageCount = (int)Math.Ceiling(dataLength * 1.0 / maxBytesPerPackage);

            PacketNetWorkMsg[] pnma = new PacketNetWorkMsg[packageCount];
            for (int i = 0; i < packageCount; i++)
            {
                int count = i == packageCount - 1 ? dataLength - maxBytesPerPackage * (packageCount - 1) : maxBytesPerPackage;

                byte[] buf = new byte[count + PackageHeaderLength];
                buf[0] = VersionHeader;                              //版本号 第1位
                BitConverter.GetBytes(packageNo).CopyTo(buf, 1);     //消息编号 第2到9位 long类型的整数
                BitConverter.GetBytes(dataLength).CopyTo(buf, 9);    //消息内容长度 第10到13位 int类型的整数
                BitConverter.GetBytes(packageCount).CopyTo(buf, 13); //分包总数 第14位到第17位 int类型的整数
                BitConverter.GetBytes(i).CopyTo(buf, 17);            //分包编号 第18位到第21位 int类型的整数
                buf[21] = RequireReceiveCheck ? (byte)1 : (byte)0;   //是否回确认包 第22位
                //第23到第31位是保留的(Reserved)
                dest.Read(buf, 32, buf.Length - 32);                 //第32字节以后是,具体的数据包

                pnma[i] = new PacketNetWorkMsg()
                {
                    Data                  = buf,
                    PackageCount          = packageCount,
                    PackageIndex          = i,
                    PackageNo             = packageNo,
                    RemoteIP              = remoteIp,
                    SendTimes             = 0,
                    Version               = 2,
                    IsRequireReceiveCheck = buf[21] == 1
                };
            }

            return(pnma);
        }