Exemplo n.º 1
0
 /// <summary>
 /// 创建一个新的 PackageEventArgs 对象.
 /// </summary>
 public PackageEventArgs(bool isMultiPackage, Entity.PackedNetworkMessage package, Entity.PackedNetworkMessage[] packages)
 {
     this.IsMultiPackage = isMultiPackage;
     this.Package        = package;
     this.Packages       = packages;
     this.IsHandled      = false;
 }
Exemplo n.º 2
0
 /// <summary>
 /// 将已经打包的消息发送出去
 /// </summary>
 /// <param name="packedMessage">已经打包的消息</param>
 /// <param name="confirmReceived">是否回发确认消息</param>
 public void Send(Entity.PackedNetworkMessage packedMessage)
 {
     if (IsInitialized)
     {
         client.Send(packedMessage.Data, packedMessage.Data.Length, packedMessage.RemoteIP);
         if (packedMessage.IsReceiveSignalRequired)
         {
             PushSendItemToList(packedMessage);
         }
     }
 }
Exemplo n.º 3
0
        /// <summary>
        /// 发送打包好的消息
        /// </summary>
        /// <param name="cm"></param>
        /// <returns>返回发出的消息包编号</returns>
        public ulong Send(Message cm)
        {
            if (!Client.IsInitialized)
            {
                return(0ul);
            }

            cm.Options |= (ulong)Define.Consts.Cmd_All_Option.EnableNewDataContract;

            MessageEventArgs mea = new MessageEventArgs(cm)
            {
                Message = cm, IsHandled = false, Host = cm.Host
            };

            OnMessageSending(mea);
            if (mea.IsHandled)
            {
                return(mea.Message.PackageNo);
            }

            //判断远程主机是否支持这个模式
            if (!Config.ForceOldContract && cm.Host != null && cm.Host.IsEnhancedContractEnabled)
            {
                Entity.PackedNetworkMessage[] pnm = MessagePackerV2.BuildNetworkMessage(cm);
                PackageEventArgs pea = new PackageEventArgs(pnm.Length > 1, pnm[0], pnm);
                OnPckageSending(pea);
                if (!pea.IsHandled)
                {
                    Array.ForEach(pnm, s => { Client.Send(s); });
                    OnPackageSended(pea);
                }
            }
            else
            {
                Entity.PackedNetworkMessage pn = MessagePacker.BuildNetworkMessage(cm);
                PackageEventArgs            pe = new PackageEventArgs(false, pn, null);
                OnPckageSending(pe);
                if (!pe.IsHandled)
                {
                    Client.Send(pn);
                    OnPackageSended(pe);
                }
            }
            OnMessageSended(mea);

            return(cm.PackageNo);
        }
Exemplo n.º 4
0
        /// <summary>
        /// 尝试将收到的网络包解析为实体
        /// </summary>
        /// <param name="pack">收到的网络包</param>
        /// <returns></returns>
        /// <remarks>如果收到的包是分片包,且其所有子包尚未接受完全,则会返回空值</remarks>
        public static IPMessager.Entity.Message TryToTranslateMessage(Entity.PackedNetworkMessage pack)
        {
            if (pack == null || pack.PackageIndex >= pack.PackageCount - 1)
            {
                return(null);
            }
            else if (pack.PackageCount == 1)
            {
                return(ParseToMessage(pack));
            }
            else
            {
                if (packageCache.ContainsKey(pack.PackageNo))
                {
                    Entity.PackedNetworkMessage[] 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
                {
                    Entity.PackedNetworkMessage[] array = new Entity.PackedNetworkMessage[pack.PackageCount];
                    array[pack.PackageIndex] = pack;
                    packageCache.Add(pack.PackageNo, array);
                    return(null);
                }
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// 尝试将收到的网络包解析为实体
        /// </summary>
        /// <param name="pack">收到的网络包</param>
        /// <returns></returns>
        /// <remarks>如果收到的包是分片包,且其所有子包尚未接受完全,则会返回空值</remarks>
        public static IPMessager.Entity.Message TryToTranslateMessage(Entity.PackedNetworkMessage pack)
        {
            if (pack == null || pack.PackageIndex >= pack.PackageCount - 1)
            {
                return(null);
            }
            if (pack.PackageCount == 1)
            {
                return(ParseToMessage(pack));
            }

            lock (packageCache)
            {
                if (packageCache.ContainsKey(pack.PackageNo))
                {
                    var array = packageCache[pack.PackageNo];
                    array[pack.PackageIndex] = pack;

                    //检测是否完整
                    //TODO 这里没有过期机制.当丢失数据包永远收不到的时候,会发生数据包永远保存在内存中的泄露
                    //TODO 要解决此问题,需要启动定时器定时检查数据包队列,并丢弃过期数据
                    if (Array.FindIndex(array, s => s == null) == -1)
                    {
                        packageCache.Remove(pack.PackageNo);
                        return(ParseToMessage(array));
                    }
                    return(null);
                }
                else
                {
                    var array = new Entity.PackedNetworkMessage[pack.PackageCount];
                    array[pack.PackageIndex] = pack;
                    packageCache.Add(pack.PackageNo, array);
                    return(null);
                }
            }
        }
Exemplo n.º 6
0
 /// <summary>
 /// 检测是否需要发送回复包来确认收到
 /// </summary>
 /// <param name="message"></param>
 /// <returns></returns>
 static bool DetermineConfirm(Entity.PackedNetworkMessage message)
 {
     return(message.IsReceiveSignalRequired);
 }
Exemplo n.º 7
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 Entity.PackedNetworkMessage[] BuildNetworkMessage(IPEndPoint remoteIp, ulong packageNo, Define.Consts.Commands command, ulong options, string userName, string hostName, byte[] content, byte[] extendContents)
		{
			options |= (ulong)Define.Consts.Cmd_Send_Option.Content_Unicode;

			//每次发送所能容下的数据量
			var maxBytesPerPackage = Define.Consts.MAX_UDP_PACKAGE_LENGTH - PackageHeaderLength;
			//压缩数据流
			var ms = new System.IO.MemoryStream();
			var zip = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Compress);
			var bw = new System.IO.BinaryWriter(zip, System.Text.Encoding.Unicode);
			//写入头部数据
			bw.Write(packageNo);						//包编号
			bw.Write(((ulong)command) | options);		//命令|选项

			bw.Write(userName);				//用户名
			bw.Write(hostName);				//主机名

			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);
			bw.Close();
			zip.Close();
			ms.Flush();
			ms.Seek(0, System.IO.SeekOrigin.Begin);

			//打包数据总量
			var dataLength = (int)ms.Length;

			var packageCount = (int)Math.Ceiling(dataLength * 1.0 / maxBytesPerPackage);
			var pnma = new PackedNetworkMessage[packageCount];
			for (var i = 0; i < packageCount; i++)
			{
				var count = i == packageCount - 1 ? dataLength - maxBytesPerPackage * (packageCount - 1) : maxBytesPerPackage;

				var buf = new byte[count + PackageHeaderLength];
				buf[0] = VersionHeader;
				BitConverter.GetBytes(packageNo).CopyTo(buf, 1);
				BitConverter.GetBytes(dataLength).CopyTo(buf, 9);
				BitConverter.GetBytes(packageCount).CopyTo(buf, 13);
				BitConverter.GetBytes(i).CopyTo(buf, 17);
				buf[21] = Define.Consts.Check(options, Define.Consts.Cmd_All_Option.RequireReceiveCheck) ? (byte)1 : (byte)0;	//包确认标志?

				ms.Read(buf, 32, buf.Length - 32);

				pnma[i] = new Entity.PackedNetworkMessage()
				{
					Data = buf,
					PackageCount = packageCount,
					PackageIndex = i,
					PackageNo = packageNo,
					RemoteIP = remoteIp,
					SendTimes = 0,
					Version = 2,
					IsReceiveSignalRequired = buf[21] == 1
				};
			}
			ms.Close();

			return pnma;
		}
Exemplo n.º 8
0
		/// <summary>
		/// 尝试将收到的网络包解析为实体
		/// </summary>
		/// <param name="pack">收到的网络包</param>
		/// <returns></returns>
		/// <remarks>如果收到的包是分片包,且其所有子包尚未接受完全,则会返回空值</remarks>
		public static IPMessager.Entity.Message TryToTranslateMessage(Entity.PackedNetworkMessage pack)
		{
			if (pack == null || pack.PackageIndex >= pack.PackageCount - 1) return null;
			if (pack.PackageCount == 1) return ParseToMessage(pack);

			lock (packageCache)
			{
				if (packageCache.ContainsKey(pack.PackageNo))
				{
					var array = packageCache[pack.PackageNo];
					array[pack.PackageIndex] = pack;

					//检测是否完整
					//TODO 这里没有过期机制.当丢失数据包永远收不到的时候,会发生数据包永远保存在内存中的泄露
					//TODO 要解决此问题,需要启动定时器定时检查数据包队列,并丢弃过期数据
					if (Array.FindIndex(array, s => s == null) == -1)
					{
						packageCache.Remove(pack.PackageNo);
						return ParseToMessage(array);
					}
					return null;
				}
				else
				{
					var array = new Entity.PackedNetworkMessage[pack.PackageCount];
					array[pack.PackageIndex] = pack;
					packageCache.Add(pack.PackageNo, array);
					return null;
				}
			}
		}
Exemplo n.º 9
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 Entity.PackedNetworkMessage[] BuildNetworkMessage(IPEndPoint remoteIp, ulong packageNo, Define.Consts.Commands command, ulong options, string userName, string hostName, byte[] content, byte[] extendContents)
        {
            options |= (ulong)Define.Consts.Cmd_Send_Option.Content_Unicode;

            //每次发送所能容下的数据量
            int maxBytesPerPackage = Define.Consts.MAX_UDP_PACKAGE_LENGTH - PackageHeaderLength;

            //压缩数据流
            System.IO.MemoryStream           ms  = new System.IO.MemoryStream();
            System.IO.Compression.GZipStream zip = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Compress);
            System.IO.BinaryWriter           bw  = new System.IO.BinaryWriter(zip, System.Text.Encoding.Unicode);
            //写入头部数据
            bw.Write(packageNo);                                        //包编号
            bw.Write(((ulong)command) | options);                       //命令|选项

            bw.Write(userName);                                         //用户名
            bw.Write(hostName);                                         //主机名

            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);
            }
            bw.Close();
            zip.Close();
            ms.Flush();
            ms.Seek(0, System.IO.SeekOrigin.Begin);

            //打包数据总量
            int dataLength = (int)ms.Length;

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

            Entity.PackedNetworkMessage[] pnma = new PackedNetworkMessage[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;
                BitConverter.GetBytes(packageNo).CopyTo(buf, 1);
                BitConverter.GetBytes(dataLength).CopyTo(buf, 9);
                BitConverter.GetBytes(packageCount).CopyTo(buf, 13);
                BitConverter.GetBytes(i).CopyTo(buf, 17);
                buf[21] = Define.Consts.Check(options, Define.Consts.Cmd_All_Option.RequireReceiveCheck) ? (byte)1 : (byte)0;                   //包确认标志?

                ms.Read(buf, 32, buf.Length - 32);

                pnma[i] = new Entity.PackedNetworkMessage()
                {
                    Data                    = buf,
                    PackageCount            = packageCount,
                    PackageIndex            = i,
                    PackageNo               = packageNo,
                    RemoteIP                = remoteIp,
                    SendTimes               = 0,
                    Version                 = 2,
                    IsReceiveSignalRequired = buf[21] == 1
                };
            }
            ms.Close();

            return(pnma);
        }