⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chatclass.cs

📁 使用C#的UDP组件制作的UDP双机通讯程序
💻 CS
📖 第 1 页 / 共 2 页
字号:
            }
            host.LastRevTick = revTick;

            switch (revKind)                                //判断消息类型
            {
                case MSG_CHAT:
                    Color revColor = Color.FromArgb(BitConverter.ToInt32(revBytes, 18));                     //颜色
                    int revMsgLen = BitConverter.ToInt32(revBytes, 22);                                     //聊天内容长度
                    string revString = Encoding.Unicode.GetString(revBytes, 26, revBytes.Length - 26);      //聊天内容
                    ReceiveDataEventArgs data = new ReceiveDataEventArgs(remote, revString, revColor);
                    LogChat(remote.Address, revString);
                    ConfirmIncept(remote);
                    FireAfterReceiveEvent(data);
                    break;
                case MSG_INCEPT:
                    m_LastSendState.Complete = ar.IsCompleted;
                    FireAfterSendEvent();
                    break;
                case MSG_UPLINE:
                    if (remote.Address.ToString() != m_LocalHostIPAddress.ToString())
                    {
                        RegisterChatHost(remote.Address);
                        FireServerStateChangeEvent(new ServerStateEventArgs(remote.Address, true));
                        RevertUpline(remote);
                    }
                    break;
                case MSG_UPLINE_REVERT:
                    FireServerStateChangeEvent(new ServerStateEventArgs(remote.Address, true));
                    break;
                case MSG_OFFLINE:
                    if (remote.Address != m_LocalHostIPAddress)
                    {
                        FireServerStateChangeEvent(new ServerStateEventArgs(remote.Address, false));
                    }
                    break;
            }
            BeginReceive();
        }

        private void BeginReceive()
        {
            try
            {
                m_UdpClient.BeginReceive(new AsyncCallback(ReceiveCallback), null);
            }
            catch(Exception ee)
            {
                Debug.WriteLine(ee.Message + ee.StackTrace);
            }
        }

        /// <summary>
        /// 消息接收确认
        /// </summary>
        private void ConfirmIncept(IPEndPoint remote)
        {
            byte[] sendBytes = MakeBaseMsgByteArray(18, MSG_INCEPT);
            m_UdpClient.Send(sendBytes, sendBytes.Length, remote.Address.ToString(), remote.Port);
        }

        /// <summary>
        /// 广播本机上线
        /// </summary>
        public void BordcaseUpline()
        {
            byte[] sendBytes = MakeBaseMsgByteArray(18, MSG_UPLINE);
            m_UdpClient.Send(sendBytes, sendBytes.Length, new IPEndPoint(IPAddress.Broadcast, LOCAL_PORT));
        }

        /// <summary>
        /// 当接收到其它主机的上线通知后,返回通知信息
        /// </summary>
        private void RevertUpline(IPEndPoint remote)
        {
            byte[] sendBytes = MakeBaseMsgByteArray(18, MSG_UPLINE_REVERT);
            m_UdpClient.Send(sendBytes, sendBytes.Length, remote);

        }
        /// <summary>
        /// 广播本机下线
        /// </summary>
        public void BordcaseOffline()
        {
            byte[] sendBytes = MakeBaseMsgByteArray(18, MSG_OFFLINE);
            m_UdpClient.Send(sendBytes, sendBytes.Length, new IPEndPoint(IPAddress.Broadcast, LOCAL_PORT));
        }

        public bool SendString(IPAddress remoteIp, string msgString, Color foreColor)
        {
            LogChat(remoteIp, msgString);
            return SendString(m_UdpClient, remoteIp, msgString, foreColor);
        }

        private static byte[] MakeBaseMsgByteArray(int len, byte msgType)
        {
            byte[] sendBytes = new byte[len];
            byte[] syncBytes = BitConverter.GetBytes(0xFFFFFFFF);           //4
            byte[] msgTick = BitConverter.GetBytes(Environment.TickCount);  //4
            byte[] msgEmpty = BitConverter.GetBytes((Int64)0);              //8
            for (int i = 0; i < 4; i++)                                     //同步
            {
                sendBytes[i] = syncBytes[i];
            }
            for (int i = 0; i < 4; i++)                                     //时间码
            {
                sendBytes[i + 4] = msgTick[i];
            }
            sendBytes[8] = MSG_VER;
            sendBytes[9] = msgType;
            for (int i = 0; i < 8; i++)
            {
                sendBytes[i + 10] = msgEmpty[i];
            }
            return sendBytes;
        }

        /// <summary>
        /// 消息数组说明:0~3->同步 4~7->时间码 8->版本号 9->消息类型 10~17->预留区 18~21->颜色 22~25->聊天内容字节数 26~...->聊天内容
        /// </summary>
        private static byte[] MakeChatByteArray(string msgString, Color foreColor)
        {
            byte[] colorBytes = BitConverter.GetBytes(foreColor.ToArgb());  //4
            byte[] msgBytes = Encoding.Unicode.GetBytes(msgString);
            byte[] msgLength = BitConverter.GetBytes(msgBytes.Length);      //4

            byte[] sendBytes = MakeBaseMsgByteArray(26 + msgBytes.Length, MSG_CHAT);
            for (int i = 0; i < 4; i++)                     //颜色
            {
                sendBytes[i + 18] = colorBytes[i];
            }
            for (int i = 0; i < 4; i++)                     //聊天内容字节数
            {
                sendBytes[i + 22] = msgLength[i];
            }
            for (int i = 0; i < msgBytes.Length; i++)       //聊天内容
            {
                sendBytes[i + 26] = msgBytes[i];
            }
            return sendBytes;
        }

        private static bool SendString(UdpClient udpClient, IPAddress remoteIp, string msgString, Color foreColor)
        {
            if (!HostIsOnline(remoteIp.ToString()))
            {
                return false;
            }
            byte[] sendBytes = MakeChatByteArray(msgString, foreColor);
            IPEndPoint remote = new IPEndPoint(remoteIp, LOCAL_PORT);
            bool result = true;
            for (int i = 0; i < 3; i++)
            {
                try
                {
                    result = udpClient.Send(sendBytes, sendBytes.Length, remote) > 0;
                    if (result) return true;
                }
                catch (Exception ee)
                {
                    Debug.WriteLine(ee.Message + ee.StackTrace);
                    result = false;
                }
            }
            return result;
        }

        public static bool SendString(int nPort, IPAddress remoteIp, string msgString, Color foreColor)
        {
            UdpClient udpClient = new UdpClient(nPort);
            udpClient.Client.SendTimeout = SEND_RECV_TIMEOUT;
            udpClient.Client.ReceiveTimeout = SEND_RECV_TIMEOUT;
            bool result = SendString(udpClient, remoteIp, msgString, foreColor);
            udpClient.Close();
            return result;
        }

        public static string GetHostNameByIp(string ip)
        {
            try
            {
                return Dns.GetHostEntry(IPAddress.Parse(ip)).HostName;
            }
            catch(Exception ee)
            {
                Debug.WriteLine(ee.Message + ee.StackTrace);
                return string.Empty;
            }
        }

        public static string GetIpByHostName(string hostName)
        {
            try
            {
                return Dns.GetHostAddresses(hostName)[0].ToString();
            }
            catch(Exception ee)
            {
                Debug.WriteLine(ee.Message + ee.StackTrace);
                return string.Empty;
            }
        }

        public static bool HostIsOnline(string ip)
        {
            if (ip == string.Empty)
            {
                return false;
            }
            Ping ping = new Ping();
            PingOptions options = new PingOptions();
            options.DontFragment = true;
            string data = "telehome";
            byte[] buffer = Encoding.Unicode.GetBytes(data);
            int timeout = 120;
            PingReply reply = ping.Send(ip, timeout, buffer, options);
            return reply.Status == IPStatus.Success;
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -