Example #1
0
        /// <summary>
        /// 通过广播发送消息
        /// </summary>
        /// <param name="cmd">命令</param>
        /// <param name="options">参数</param>
        /// <param name="normalMsg">常规信息</param>
        /// <param name="extendMessage">扩展消息</param>
        /// <param name="sendCheck">是否检查发送到</param>
        /// <returns>返回发出的消息包编号</returns>
        public void Send(Define.Consts.Commands cmd, ulong options, string normalMsg, string extendMessage)
        {
            if (!Client.IsInitialized)
            {
                return;
            }

            SendWithNoCheck(null, cmd, options, normalMsg, extendMessage);
        }
Example #2
0
        /// <summary>
        /// 发送消息并且要求对方返回已接收消息
        /// </summary>
        /// <param name="host">远程主机.如果为null则会抛出异常</param>
        /// <param name="cmd">命令</param>
        /// <param name="options">参数</param>
        /// <param name="normalMsg">常规信息</param>
        /// <param name="extendMessage">扩展消息</param>
        /// <param name="sendCheck">是否检查发送到</param>
        /// <returns>返回发出的消息包编号</returns>
        public ulong SendWithCheck(Host host, Define.Consts.Commands cmd, ulong options, byte[] normalMsg, byte[] extendMessage)
        {
            if (host == null)
            {
                throw new ArgumentNullException("host");
            }

            return(Send(host, host.HostSub.Ipv4Address, cmd, options, normalMsg, extendMessage, true));
        }
Example #3
0
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="remoteEndPoint">远程主机地址</param>
        /// <param name="cmd">命令</param>
        /// <param name="options">参数</param>
        /// <param name="normalMsg">常规信息</param>
        /// <param name="extendMessage">扩展消息</param>
        /// <param name="sendCheck">是否检查发送到</param>
        /// <returns>返回发出的消息包编号</returns>
        public ulong Send(Host host, IPEndPoint remoteEndPoint, Define.Consts.Commands cmd, ulong options, string normalMsg, string extendMessage, bool sendCheck)
        {
            Message cm = Message.Create(host, remoteEndPoint, Config.GetRandomTick(), Config.HostName, Config.HostUserName,
                                        cmd, options, normalMsg, extendMessage);

            if (sendCheck)
            {
                cm.IsRequireReceiveCheck = sendCheck;
            }

            return(Send(cm));
        }
Example #4
0
        /// <summary>
        /// 以二进制模式发送消息
        /// </summary>
        /// <param name="host">关联的远程主机,不可以为null</param>
        /// <param name="remoteEndPoint">远程主机地址</param>
        /// <param name="cmd">命令</param>
        /// <param name="options">参数</param>
        /// <param name="normalMsg">常规信息</param>
        /// <param name="extendMessage">扩展消息</param>
        /// <param name="sendCheck">是否检查发送到</param>
        /// <exception cref="InvalidOperationException">如果对方主机不在列表中,或未知是否支持增强协议,则会抛出此异常</exception>
        /// <returns>返回发出的消息包编号</returns>
        public ulong Send(Host host, IPEndPoint remoteEndPoint, Define.Consts.Commands cmd, ulong options, byte[] normalMsg, byte[] extendMessage, bool sendCheck)
        {
            if (!Client.IsInitialized)
            {
                return(0ul);
            }

            //判断远程主机是否支持这个模式
            if (host == null || !host.IsEnhancedContractEnabled)
            {
                throw new InvalidOperationException("尚不知道主机是否支持增强协议模式,无法以二进制模式发送消息!");
            }

            Message cm = Message.Create(host, remoteEndPoint, Config.GetRandomTick(), Config.HostName, Config.NickName,
                                        cmd, options, "", "");

            cm.ExtendMessageBytes    = extendMessage;
            cm.NormalMsgBytes        = normalMsg;
            cm.IsRequireReceiveCheck = sendCheck;

            //设置选项
            if (sendCheck)
            {
                cm.Options |= (ulong)Define.Consts.Cmd_All_Option.RequireReceiveCheck;
            }
            cm.Options |= (ulong)Define.Consts.Cmd_All_Option.EnableNewDataContract | (ulong)Define.Consts.Cmd_All_Option.BinaryMessage;

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

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

            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);
            }
            OnMessageSended(mea);

            return(cm.PackageNo);
        }
Example #5
0
 /// <summary>
 /// 直接向目标IP发送信息
 /// </summary>
 /// <param name="host">远程主机</param>
 /// <param name="cmd">命令</param>
 /// <param name="options">参数</param>
 /// <param name="normalMsg">常规信息</param>
 /// <param name="extendMessage">扩展消息</param>
 /// <param name="sendCheck">是否检查发送到</param>
 /// <returns>返回发出的消息包编号</returns>
 public ulong SendByIp(IPEndPoint remoteEndPoint, Define.Consts.Commands cmd, ulong options, string normalMsg, string extendMessage)
 {
     return(Send(null, remoteEndPoint ?? broadcastEndPoint, cmd, options, normalMsg, extendMessage, false));
 }
Example #6
0
 /// <summary>
 /// 发送消息
 /// </summary>
 /// <param name="host">远程主机</param>
 /// <param name="cmd">命令</param>
 /// <param name="options">参数</param>
 /// <param name="normalMsg">常规信息</param>
 /// <param name="extendMessage">扩展消息</param>
 /// <param name="sendCheck">是否检查发送到</param>
 /// <returns>返回发出的消息包编号</returns>
 public ulong SendWithNoCheck(Host host, Define.Consts.Commands cmd, ulong options, string normalMsg, string extendMessage)
 {
     return(Send(host, host == null ? broadcastEndPoint : host.HostSub.Ipv4Address, cmd, options, normalMsg, extendMessage, false));
 }
Example #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;

            //每次发送所能容下的数据量
            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);
        }
Example #8
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)
        {
            using (System.IO.MemoryStream bufferStream = new System.IO.MemoryStream())
            {
                int    maxLength = Consts.MAX_UDP_PACKAGE_LENGTH;
                byte[] buffer;

                /*
                 * 注意:
                 * 1.优先保证扩展信息,如果不能保证则返回失败
                 * 2.保证扩展消息的前提下,文本消息可以截取
                 * */
                //写入消息头
                ulong cmdInfo = (ulong)command | options;
                buffer = System.Text.Encoding.Default.GetBytes(string.Format("{0}:{1}:{2}:{3}:{4}:", (char)Consts.VersionNumber, packageNo, userName, hostName, cmdInfo));
                bufferStream.Write(buffer, 0, buffer.Length);
                //计算扩展消息
                int extendMessageLength = extendContents == null ? 0 : extendContents.Length;
                if (extendMessageLength + bufferStream.Length > maxLength)
                {
                    extendContents = null;
                }
                extendMessageLength = extendContents == null ? 0 : extendContents.Length + 1;
                //写入文本消息
                if (content != null)
                {
                    if (content.Length <= maxLength - extendMessageLength - bufferStream.Length)
                    {
                        bufferStream.Write(content, 0, content.Length);
                    }
                    else
                    {
                        bufferStream.Write(content, 0, maxLength - extendMessageLength - (int)bufferStream.Length);
                    }
                }
                //写入扩展消息?
                if (extendMessageLength > 0)
                {
                    bufferStream.WriteByte(0);
                    bufferStream.Write(extendContents, 0, extendMessageLength - 1);
                }
                bufferStream.Seek(0, System.IO.SeekOrigin.Begin);
                buffer = bufferStream.ToArray();

                return(new Entity.PackedNetworkMessage()
                {
                    PackageCount = 1,
                    PackageIndex = 0,
                    Data = buffer,
                    SendTimes = 0,
                    PackageNo = packageNo,
                    RemoteIP = remoteIp,
                    //回避BUG:全局参数里面,Absence 选项和 SendCheck 是一样的
                    IsReceiveSignalRequired = command != Consts.Commands.Br_Absence && Define.Consts.Check(options, Consts.Cmd_Send_Option.SendCheck) && remoteIp.Address != IPAddress.Broadcast,
                    Version = 0
                });
            }
        }