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

📄 chatclass.cs

📁 使用C#的UDP组件制作的UDP双机通讯程序
💻 CS
📖 第 1 页 / 共 2 页
字号:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Threading;
using System.Drawing;
using System.Diagnostics;
using System.Collections;
using System.IO;
using System.Xml;

namespace Th.ChatLib
{
    public delegate void DelegateAfterReceive(ReceiveDataEventArgs e);
    public delegate void DelegateAfterSend(SendStateEventArgs e);
    public delegate void DelegateRemoteStateChange(ServerStateEventArgs e);

    public class ChatClass
    {
        private class ChatHost
        {
            private IPAddress m_IP;
            public IPAddress IP
            {
                get { return m_IP; }
            }
            public string IPString
            {
                get { return m_IP.ToString(); }
            }

            private int m_LastRevTick;
            public int LastRevTick
            {
                get { return m_LastRevTick; }
                set { m_LastRevTick = value; }
            }

            public ChatHost(IPAddress ip, int lastRevTick)
            {
                m_IP = ip;
                m_LastRevTick = lastRevTick;
            }
        }

        private ArrayList m_ChatHostList = new ArrayList();

        private ChatHost RegisterChatHost(IPAddress ip)
        {
            foreach (ChatHost chatHost in m_ChatHostList)
            {
                if (chatHost.IPString == ip.ToString())
                {
                    return chatHost;
                }
            }
            ChatHost host = new ChatHost(ip, 0);
            m_ChatHostList.Add(host);
            return host;
        }

        private ChatHost GetChatHost(IPAddress ip)
        {
            foreach (ChatHost host in m_ChatHostList)
            {
                if (host.IPString == ip.ToString())
                {
                    return host;
                }
            }
            return null;
        }

        /// <summary>
        /// 发送和接收的超时等待时间
        /// </summary>
        private const int SEND_RECV_TIMEOUT = 100;

        private const int LOCAL_PORT = 51533;
        /// <summary>
        /// 版本号
        /// </summary>
        private const byte MSG_VER = 1;
        /// <summary>
        /// 聊天信息
        /// </summary>
        private const byte MSG_CHAT = 1;
        /// <summary>
        /// 上线通知
        /// </summary>
        private const byte MSG_UPLINE = 2;
        /// <summary>
        /// 下线通知
        /// </summary>
        private const byte MSG_OFFLINE = 3;
        /// <summary>
        /// 信息接收确认
        /// </summary>
        private const byte MSG_INCEPT = 4;
        /// <summary>
        /// 上线通知回复
        /// </summary>
        private const byte MSG_UPLINE_REVERT = 5;

        private SendStateEventArgs m_LastSendState = new SendStateEventArgs(false);

        public SendStateEventArgs LastSendState
        {
            get { return m_LastSendState; }
        }

        public event DelegateAfterReceive AfterReceive;
        public event DelegateAfterSend AfterSend;
        public event DelegateRemoteStateChange ServerStateChange;

        private void FireServerStateChangeEvent(ServerStateEventArgs e)
        {
            if (ServerStateChange != null) ServerStateChange(e);
        }

        private void FireAfterReceiveEvent(ReceiveDataEventArgs e)
        {
            if (AfterReceive != null) AfterReceive(e);
        }

        private void FireAfterSendEvent()
        {
            if (AfterSend != null) AfterSend(m_LastSendState);
        }

        private UdpClient m_UdpClient;

        private string m_LocalHostName;
        public string LocalHostName
        {
            get { return m_LocalHostName; }
        }

        private IPAddress m_LocalHostIPAddress;
        public IPAddress LocalHostIPAddress
        {
            get { return m_LocalHostIPAddress; }
        }

        private string m_LogPath;
        private FileStream m_ChatFile;
        private StreamWriter m_ChatWriter;

        public ChatClass(string logPath)
        {
            m_LogPath = logPath;
            m_LocalHostName = Dns.GetHostName();
            m_LocalHostIPAddress = Dns.GetHostAddresses(m_LocalHostName)[0];
        }

        public void StartWork()
        {
            Directory.CreateDirectory(m_LogPath);
            m_ChatFile = new FileStream(Path.Combine(m_LogPath, string.Format("{0:000}-{1:00}-{2:00}.txt", DateTime.Now.Year, 
                DateTime.Now.Month, DateTime.Now.Day)), FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);
            m_ChatFile.Seek(0, SeekOrigin.End);
            m_ChatWriter = new StreamWriter(m_ChatFile, Encoding.Unicode);

            m_UdpClient = new UdpClient(new IPEndPoint(IPAddress.Any, LOCAL_PORT));
            m_UdpClient.Client.ReceiveTimeout = SEND_RECV_TIMEOUT;
            m_UdpClient.Client.SendTimeout = SEND_RECV_TIMEOUT;
            m_UdpClient.BeginReceive(new AsyncCallback(ReceiveCallback), null);
        }

        public void StopWork()
        {
            m_UdpClient.Close();

            m_ChatWriter.Flush();
            m_ChatWriter.Close();
            m_ChatFile.Close();
        }

        private void LogChat(IPAddress addr, string chatString)
        {
            string logString = string.Format("{0}\t{1}\t{2}\t{3}", 
                DateTime.Now.ToLongDateString(), 
                DateTime.Now.ToLongTimeString(), 
                addr, 
                chatString);
            m_ChatWriter.WriteLine(logString);
        }

        private void SendCallback(IAsyncResult ar)
        {
            m_LastSendState.Complete = false;
            m_UdpClient.EndSend(ar);
        }

        private void ReceiveCallback(IAsyncResult ar)
        {
            IPEndPoint remote = new IPEndPoint(IPAddress.Any, LOCAL_PORT);
            byte[] revBytes = new byte[26];                              //初始化接收区
            try
            {
                revBytes = m_UdpClient.EndReceive(ar, ref remote);
            }
            catch(Exception ee)                                                     //网络异常
            {
                m_LastSendState.Complete = false;
                FireAfterSendEvent();
                Debug.WriteLine(ee.Message + ee.StackTrace);
            }

            int syncHeader = BitConverter.ToInt32(revBytes, 0); //同步
            int revTick = BitConverter.ToInt32(revBytes, 4);    //时间码
            byte revVer = revBytes[8];                          //消息版本号
            byte revKind = revBytes[9];                         //消息类型

            ChatHost host = RegisterChatHost(remote.Address);   //判断时间码
            if (host.LastRevTick == revTick)                    
            {
                BeginReceive();
                return;

⌨️ 快捷键说明

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