[unity3d]unity聊天功能

感觉之前的聊天功能可能有一些缺陷,今天收到书华兄的启发,发表一些感慨,C# .net高手跟新手的区别就是,新手仅仅满足功能上的实现,而很少去考虑性能上的问题,比如高并发怎么处理,打个比方,新手做完聊天功能之后,会沾沾自喜,而不考虑最大客户连接有多少,做个实验,如果连续有四个左右的客户端同时连接到服务器端,服务器就要消耗将近200M的内存,这时机器可怕的事情,如果不做处理的话,假设几百人去连接,估计服务器端就要崩溃了,还有一点高手喜欢写封装,将功能进行高度封装给新手用,新手用完了人家封装的类库,然后简单代码就实现功能了,也会沾沾自喜,津津乐道,这样就会止步不前!用了一下封装的类库来写unity聊天客户端果真非常快,几行代码就搞定!

unity客户端:

UI:

[csharp]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class chart : MonoBehaviour {  
  5.   
  6.     string txtmsg = "";  
  7.     public string txtServer = "192.168.1.24";  
  8.     string txtLog = "";  
  9.     public string txtPort = "50000";  
  10.     ClientLibrary.Client client;  
  11.     ClientLibrary.Model model = new ClientLibrary.Model();  
  12.     // Use this for initialization  
  13.     void Start () {  
  14.       
  15.     }  
  16.   
  17.     bool flag = true;  
  18.     // Update is called once per frame  
  19.     void Update () {  
  20.         if(client.HeartDataSend()!=1)  
  21.         {  
  22.             SetTxt("请检查网络你已经掉线,可能原因服务器出错,请重新连接");  
  23.             client.KillSocket();  
  24.             flag = false;  
  25.         }  
  26.     }  
  27.   
  28.     void OnGUI()  
  29.     {  
  30.         txtServer = GUI.TextField(new Rect(10f,20f,100f,20f),txtServer);  
  31.         txtLog = GUI.TextField (new Rect(50f,40f,200f,200f),txtLog);  
  32.         if(GUI.Button(new Rect(120f,20f,50f,20f),"start")&&flag)  
  33.         {  
  34.             model.TxtServer = txtServer;  
  35.             model.TxtPort = txtPort;  
  36.             bool enable;  
  37.             client = new ClientLibrary.Client(model,SetTxt,out enable);  
  38.             if(enable)  
  39.             {  
  40.                 //txtLog = "123";  
  41.             }  
  42.             else  
  43.             {  
  44.                 //txtLog = "no";  
  45.             }  
  46.             flag = false;  
  47.         }  
  48.     }  
  49.     void SetTxt(string msg)  
  50.     {  
  51.         txtLog+=msg+"\r\n";  
  52.     }  
  53. }  

ChatClient:

[csharp]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. using System.Net.Sockets;  
  2. using System.Text;  
  3. using System.Threading;  
  4.   
  5. namespace ClientLibrary  
  6. {  
  7.     #region 委托  
  8.     /// <summary>  
  9.     /// 信息显示委托  
  10.     /// </summary>  
  11.     /// <param name="msg">需要打印到前台的信息</param>  
  12.     public delegate void deMessageShow(string msg);  
  13.     /// <summary>  
  14.     /// 文件保存委托  
  15.     /// </summary>  
  16.     /// <param name="buffer">保存的文件数据</param>  
  17.     /// <param name="count">文件大小</param>  
  18.     /// <returns></returns>  
  19.     public delegate bool deGetFileStream(byte[] buffer,int count);  
  20.     /// <summary>  
  21.     /// 客户端震动 委托  
  22.     /// </summary>  
  23.     public delegate void deZD();  
  24.     #endregion  
  25.     /// <summary>  
  26.     /// 客户端实体类  
  27.     /// </summary>  
  28.     public class Model  
  29.     {  
  30.         private string txtMsg;  
  31.   
  32.         public string TxtMsg  
  33.         {  
  34.             get { return txtMsg; }  
  35.             set { txtMsg = value; }  
  36.         }  
  37.         private string txtPort;  
  38.   
  39.         public string TxtPort  
  40.         {  
  41.             get { return txtPort; }  
  42.             set { txtPort = value; }  
  43.         }  
  44.        private string txtServer;  
  45.   
  46.         public string TxtServer  
  47.         {  
  48.             get { return txtServer; }  
  49.             set { txtServer = value; }  
  50.         }  
  51.     }  
  52.     /// <summary>  
  53.     /// 客户端方法类  
  54.     /// </summary>  
  55.     public class Client  
  56.     {  
  57.         public Client(Model model,deMessageShow messageShowFun,out bool enable)  
  58.         {  
  59.             messageShow = messageShowFun;  
  60.             lastTimeRecive = DateTime.Now;  
  61.             if (CreateClientSocket(model)) //创建Socket  
  62.             {  
  63.                 enable = true;  
  64.                 return;  
  65.             }  
  66.             enable = false;       
  67.         }  
  68.         public Client(Model model, deMessageShow message, deGetFileStream saveFileFun, out bool enable)  
  69.         {  
  70.             messageShow = message;  
  71.             getFileStream = saveFileFun;  
  72.             lastTimeRecive = DateTime.Now;  
  73.              if (CreateClientSocket(model))//创建Socket  
  74.             {  
  75.                 enable = true;  
  76.                 return;  
  77.             }  
  78.              enable = false;  
  79.         }  
  80.         public Client(Model model, deMessageShow message, deGetFileStream saveFileFun, deZD zdFun, out bool enable)  
  81.         {  
  82.             messageShow = message;  
  83.             getFileStream = saveFileFun;  
  84.             lastTimeRecive = DateTime.Now;  
  85.               if (!CreateClientSocket(model)) //创建Socket  
  86.             {  
  87.                 enable = true;  
  88.                 return;  
  89.             }  
  90.               enable = false;  
  91.         }  
  92.         Model model = new Model();  
  93.         /// <summary>  
  94.         ///  通信Scoket  
  95.         /// </summary>  
  96.         Socket connSocket;  
  97.         /// <summary>  
  98.         /// 通信线程  
  99.         /// </summary>  
  100.         Thread thmsg;  
  101.         /// <summary>  
  102.         /// 最后一次接受数据时间  
  103.         /// </summary>  
  104.         public DateTime lastTimeRecive;  
  105.         /// <summary>  
  106.         /// 最后一次发送数据时间  
  107.         /// </summary>  
  108.         public DateTime lastTimeSend;  
  109.         #region 声明委托  
  110.      public   deMessageShow messageShow;  
  111.       public  deGetFileStream getFileStream;  
  112.      public   deZD zD;  
  113.         #endregion  
  114.   
  115.         /// <summary>  
  116.         /// 创建客户端Socket  
  117.         /// </summary>  
  118.         /// <param name="ModelUI"></param>  
  119.         /// <returns>创建状态</returns>  
  120.         public bool CreateClientSocket(Model ModelUI)  
  121.         {  
  122.             model = ModelUI;  
  123.             bool enabel = false;   
  124.             //服务器IP  
  125.             IPAddress ipServer = IPAddress.Parse(model.TxtServer);  
  126.             //创建 终端地址  
  127.             IPEndPoint endPointServer = new IPEndPoint(ipServer, int.Parse(model.TxtPort));  
  128.             //创建 连接socket connSocket  
  129.            connSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  
  130.             try  
  131.             {  
  132.                 connSocket.Connect(endPointServer);  
  133.                 messageShow("登陆成功");  
  134.                 #region  创建接受信息的线程  
  135.                 thmsg = new Thread(ReciveMsg);  
  136.                 thmsg.IsBackground = true;  
  137.                 thmsg.Start();  
  138.                 #endregion  
  139.             }  
  140.             catch (Exception ex)  
  141.             {  
  142.                 messageShow(ex.Message);  
  143.                enabel= true;  
  144.             }  
  145.             return enabel;  
  146.         }  
  147.   
  148.         /// <summary>  
  149.         /// 信息接收  
  150.         /// </summary>  
  151.         private void ReciveMsg()  
  152.         {  
  153.             //0 文字 1 文件 2 震动  
  154.             byte[] buffer = new byte[5 * 1024 * 1024];  
  155.             while (true)  
  156.             {  
  157.                 int count = connSocket.Receive(buffer);  
  158.                 int flag = buffer[0];  
  159.                 if (count == 0)  
  160.                 {  
  161.                     connSocket.Close();  
  162.                     messageShow("你掉线或者服务器关系");  
  163.                     break;  
  164.                 }  
  165.                 Recive(buffer, count, flag);  
  166.             }  
  167.         }  
  168.  
  169.         #region 必要方法  
  170.         #region 接收+Recive(byte[] buffer, int count,int flag)  
  171.         /// <summary>  
  172.         /// 处理接受的信息  
  173.         /// </summary>  
  174.         /// <param name="buffer"></param>  
  175.         /// <param name="count"></param>  
  176.         /// <param name="flag"></param>  
  177.         private void Recive(byte[] buffer, int count, int flag)  
  178.         {  
  179.             if (flag == 0)  
  180.             {  
  181.                 #region flag=0 文字信息  
  182.                 string msg = Encoding.UTF8.GetString(buffer, 1, count - 1);  
  183.                 messageShow("服务器 : " + msg);  
  184.                 #endregion  
  185.             }  
  186.             else if (flag == 1)  
  187.             {  
  188.                 #region flag=1 传送文件  
  189.                 if (getFileStream(buffer,count))  
  190.                 {  
  191.                     messageShow("接受完成");  
  192.                 }             
  193.                 #endregion  
  194.             }  
  195.             else if (flag == 2)  
  196.             {  
  197.                 #region flag=2 震动  
  198.                 zD();  
  199.                 #endregion  
  200.             }  
  201.             else if (flag == 3)  
  202.             {  
  203.                 string atat=Encoding.UTF8.GetString(buffer,1,count-1);  
  204.                 if (atat == "ATAT")  
  205.                 {  
  206.                     lastTimeRecive = DateTime.Now;  
  207.                 }  
  208.             }  
  209.         }  
  210.  
  211.  
  212.         #endregion  
  213.         /// <summary>  
  214.         /// 发送心跳包  
  215.         /// </summary>  
  216.         /// <returns>发送状态</returns>  
  217.         public int HeartDataSend()  
  218.         {  
  219.             lastTimeSend = DateTime.Now;  
  220.             if (DateTime.Now.Second - lastTimeRecive.Second > 3)  
  221.             {  
  222.                 return 3;  
  223.             }  
  224.             if (connSocket != null && connSocket.Connected)  
  225.             {  
  226.                 try  
  227.                 {  
  228.                     byte[] buffer = Encoding.UTF8.GetBytes("NTNT");  
  229.                     connSocket.Send(buffer);  
  230.                     lastTimeRecive = DateTime.Now;  
  231.                     return 1;  
  232.                 }  
  233.                 catch (Exception ex)  
  234.                 {  
  235.                    // messageShow(ex.Message);  
  236.                     return 2;  
  237.                 }  
  238.             }  
  239.             return 1;  
  240.         }  
  241.         /// <summary>  
  242.         /// 数据发送  
  243.         /// </summary>  
  244.         /// <returns></returns>  
  245.         public bool Send()  
  246.         {  
  247.             if (connSocket != null && connSocket.Connected)  
  248.             {  
  249.                 try  
  250.                 {  
  251.                     byte[] buffer = new byte[1024 * 1024 * 5];  
  252.                     buffer = Encoding.UTF8.GetBytes(model.TxtMsg);  
  253.                     connSocket.Send(buffer);  
  254.                     lastTimeRecive = DateTime.Now;  
  255.                     return true;  
  256.                 }  
  257.                 catch (Exception ex)  
  258.                 {  
  259.                     messageShow(ex.Message);  
  260.                     return false;  
  261.                 }  
  262.             }  
  263.             return false;  
  264.         }  
  265.   
  266.         /// <summary>  
  267.         /// 终止连接  
  268.         /// </summary>  
  269.         public void KillSocket()  
  270.         {  
  271.             if (thmsg != null)  
  272.             {  
  273.                 thmsg.Abort();  
  274.             }  
  275.             if (connSocket != null && connSocket.Connected)  
  276.             {  
  277.                 connSocket.Shutdown(SocketShutdown.Both);  
  278.                 connSocket.Close();  
  279.             }  
  280.         }  
  281.         #endregion  
  282.     }  
  283. }  

服务器端:

Server:

[csharp]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.IO;  
  4. using System.Linq;  
  5. using System.Net;  
  6. using System.Net.Sockets;  
  7. using System.Text;  
  8. using System.Threading;  
  9.   
  10. namespace ServerChatClass  
  11. {  
  12.     #region 委托  
  13.     /// <summary>  
  14.     /// 信息显示委托  
  15.     /// </summary>  
  16.     /// <param name="msg">需要打印到前台的信息</param>  
  17.     public delegate void deMessageShow(string msg);  
  18.     /// <summary>  
  19.     /// 注册客户端ednpoing和Socket,Thread  
  20.     /// </summary>  
  21.     /// <param name="endpoing">注册地址</param>  
  22.     public delegate void deRegisterClientIP(string endpoing);  
  23.     /// <summary>  
  24.     /// 从UI上移除客户端显示  
  25.     /// </summary>  
  26.     /// <param name="endpoing">客户端地址或者名称</param>  
  27.     public delegate void deRemoveClientIPFromUI(string endpoing);  
  28.     #endregion  
  29.     /// <summary>  
  30.     /// 实体类  
  31.     /// </summary>  
  32.     public class Model  
  33.     {  
  34.         private string txtMsg;  
  35.         private string txtPath;  
  36.   
  37.         private string txtLog;  
  38.         private string txtServer;  
  39.         private string txtPort;  
  40.   
  41.         private string clientEndPoint;  
  42.         /// <summary>  
  43.         /// 客户端地址  
  44.         /// </summary>  
  45.         public string ClientEndPoint  
  46.         {  
  47.             get { return clientEndPoint; }  
  48.             set { clientEndPoint = value; }  
  49.         }  
  50.         /// <summary>  
  51.         /// 端口  
  52.         /// </summary>  
  53.         public string TxtPort  
  54.         {  
  55.             get { return txtPort; }  
  56.             set { txtPort = value; }  
  57.         }  
  58.         /// <summary>  
  59.         /// IP  
  60.         /// </summary>  
  61.         public string TxtServer  
  62.         {  
  63.             get { return txtServer; }  
  64.             set { txtServer = value; }  
  65.         }  
  66.         /// <summary>  
  67.         /// 日志  
  68.         /// </summary>  
  69.         public string TxtLog  
  70.         {  
  71.             get { return txtLog; }  
  72.             set { txtLog = value; }  
  73.         }  
  74.         /// <summary>  
  75.         /// 文件地址  
  76.         /// </summary>  
  77.         public string TxtPath  
  78.         {  
  79.             get { return txtPath; }  
  80.             set { txtPath = value; }  
  81.         }  
  82.         /// <summary>  
  83.         /// 消息文字发送  
  84.         /// </summary>  
  85.         public string TxtMsg  
  86.         {  
  87.             get { return txtMsg; }  
  88.             set { txtMsg = value; }  
  89.         }  
  90.   
  91.     }  
  92.     public class Request  
  93.     {  
  94.         public Request(string msg)  
  95.         {  
  96.             if (msg.Length < 100)  
  97.             { return; }  
  98.             try  
  99.             {  
  100.                 string[] lines = msg.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);  
  101.                 string firstLine = lines[0];  
  102.                 string[] array = firstLine.Split(' ');  
  103.                 method = array[0];  
  104.                 url = array[1];  
  105.             }  
  106.             catch (Exception)  
  107.             {  
  108.   
  109.             }  
  110.   
  111.         }  
  112.         private string method;  
  113.         public string Method  
  114.         {  
  115.             get { return method; }  
  116.             set { method = value; }  
  117.         }  
  118.         private string url;  
  119.         public string Url  
  120.         {  
  121.             get { return url; }  
  122.             set { url = value; }  
  123.         }  
  124.     }  
  125.     public class SeverChar  
  126.     {  
  127.  
  128.         #region 客户机注册字典  
  129.         /// <summary>  
  130.         /// 客户端地址clientIP和对应最后一次通信时间  
  131.         /// </summary>  
  132.         public Dictionary<string, DateTime> dicListTimeConnSocket = new Dictionary<string, DateTime>();  
  133.         /// <summary>  
  134.         /// 客户端地址clinetIP和对应的通信Socket  
  135.         /// </summary>  
  136.         public Dictionary<string, Socket> dicConnSocket = new Dictionary<string, Socket>();  
  137.         /// <summary>  
  138.         /// 客户端地址clientIP和对应通信线程ThreadMsg  
  139.         /// </summary>  
  140.         public Dictionary<string, Thread> dicThreadMsg = new Dictionary<string, Thread>();  
  141.         #endregion  
  142.         #region 委托声明  
  143.         /// <summary>  
  144.         /// 消息显示  
  145.         /// </summary>  
  146.         public deMessageShow messageShow;  
  147.         /// <summary>  
  148.         /// 注册客户机  
  149.         /// </summary>  
  150.         public deRegisterClientIP registerClientIP;  
  151.         /// <summary>  
  152.         /// 从UI上移除客户端显示  
  153.         /// </summary>  
  154.         public deRemoveClientIPFromUI removeClientIPFromUI;  
  155.         #endregion  
  156.         /// <summary>  
  157.         /// 初始化程序  
  158.         /// </summary>  
  159.         /// <param name="downline">掉线信息</param>  
  160.   
  161.         public SeverChar(string msg,Model model, deMessageShow messageShowFun, string downline, out bool enable)  
  162.         {  
  163.             messageShow = messageShowFun;  
  164.             if (CreateServerMonitorSorcket(model,msg)) //创建Socket  
  165.             {  
  166.                 enable = true;  
  167.             }  
  168.             else  
  169.             {  
  170.                 enable = false;  
  171.             }  
  172.         }  
  173.         public SeverChar(string msg,Model model, deMessageShow messageShowFun,deRegisterClientIP registerClientIPFun ,string downline, out bool enable)  
  174.         {  
  175.             registerClientIP = registerClientIPFun;  
  176.             messageShow = messageShowFun;  
  177.             if (CreateServerMonitorSorcket(model, msg))//创建Socket  
  178.             {  
  179.                 enable = true;  
  180.             }  
  181.             else  
  182.             {  
  183.                 enable = false;  
  184.             }  
  185.         }  
  186.         public SeverChar(string msg,Model model, deMessageShow messageShowFun, deRegisterClientIP registerClientIPFun, deRemoveClientIPFromUI removerClientIPFormUIFun,string downline, out bool enable)  
  187.         {  
  188.             removeClientIPFromUI = removerClientIPFormUIFun;  
  189.             registerClientIP = registerClientIPFun;  
  190.             messageShow = messageShowFun;  
  191.             if (CreateServerMonitorSorcket(model, msg)) //创建Socket  
  192.             {  
  193.                 enable = true;  
  194.             }  
  195.             else  
  196.             {  
  197.                 enable=false;  
  198.             }  
  199.         }  
  200.         public SeverChar(string downline)  
  201.         {  
  202.             downLine = downline;  
  203.         }  
  204.         /// <summary>  
  205.         /// 需要发送请求的通信Socket  
  206.         /// </summary>  
  207.         public List<Socket> listSendConnSocket = new List<Socket>();  
  208.         /// <summary>  
  209.         /// 掉线信息提示  
  210.         /// </summary>  
  211.         public string downLine;  
  212.         Socket socketServer;//监听socket  
  213.         Model modelSever = new Model();  
  214.         object o = new object();  
  215.  
  216.         #region 创建监听的socket socketServer+public bool CreateServerMonitorSorcket(Model model, string msg)  
  217.         /// <summary>  
  218.         /// 服务器创建监听的socket socketServer  
  219.         /// </summary>  
  220.         /// <param name="model">监听实体,包含监听端口和IP</param>  
  221.         /// <param name="msg">监听成功后显示的信息</param>  
  222.         /// <returns></returns>  
  223.         public bool CreateServerMonitorSorcket(Model model, string msg)  
  224.         {  
  225.             modelSever = model;  
  226.             bool enable;  
  227.             Socket socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  
  228.             #  region 其他测试  
  229.             //IPHostEntry host = new IPHostEntry();  
  230.             //host.  
  231.             #endregion  
  232.             //Ip地址  
  233.             IPAddress ipServer = IPAddress.Parse(model.TxtServer);  
  234.             //ip地址和端口  
  235.             IPEndPoint endPointServer = new IPEndPoint(ipServer, int.Parse(model.TxtPort));  
  236.             try  
  237.             {  
  238.                 //绑定网络端点  
  239.                 socketServer.Bind(endPointServer);  
  240.                 //设置排队长度  
  241.                 socketServer.Listen(10);  
  242.                 messageShow(msg);  
  243.                 #region 用连接连接线程ThreadConnSockt  创建通信Socket 防止阻塞卡死+Listen(object)  
  244.                 Thread threadConnSocket = new Thread(Listen);  
  245.                 threadConnSocket.Name = "conn";  
  246.                 threadConnSocket.IsBackground = true;  
  247.                 threadConnSocket.Start(socketServer);  
  248.                 #endregion  
  249.                 enable = true;  
  250.             }  
  251.             catch (Exception ex)  
  252.             {  
  253.                 messageShow(ex.Message);  
  254.                 enable = false;  
  255.             }  
  256.             return enable;  
  257.         }  
  258.         #endregion  
  259.  
  260.         #region 创建服务端通信Socket  connSocket单线程会阻塞窗体运行+Listen(object)  
  261.         /// <summary>  
  262.         /// 创建通信Socket  
  263.         /// </summary>  
  264.         /// <param name="socket"></param>  
  265.         public void Listen(object socket)  
  266.         {  
  267.             socketServer = socket as Socket;  
  268.             while (true)  
  269.             {  
  270.                 Socket connSocket = socketServer.Accept();//阻塞等待 客户端连接  
  271.                 string clinetEndPing = connSocket.RemoteEndPoint.ToString();//获取客户端通信地址  
  272.                 messageShow(clinetEndPing+"登陆");  
  273.                 #region 新建通信监听线程threadMsg 接收客户端发送过来的信息  
  274.                 Thread threadMsg = new Thread(ReciveMsg);               
  275.                 threadMsg.Name = "msg";  
  276.                 threadMsg.IsBackground = true;  
  277.                 threadMsg.Start(connSocket);  
  278.                 RegisterClientAtSever(clinetEndPing, threadMsg, connSocket);  
  279.                 #endregion  
  280.             }  
  281.         }  
  282.         #endregion  
  283.         #region 接收客户端发送的信息 ReciveMsg(object socket)  
  284.         /// <summary>  
  285.         /// 接收客户端发送的信息 方法  
  286.         /// </summary>  
  287.         /// <param name="socket">发送信息的socket</param>  
  288.         public void ReciveMsg(object socket)  
  289.         {  
  290.             Socket connSocket = socket as Socket;  
  291.             string clineteEndPoint = connSocket.RemoteEndPoint.ToString();  
  292.             byte[] buffer = new byte[1024 * 1024 * 5];  
  293.             while (true)  
  294.             {  
  295.                 int count = connSocket.Receive(buffer);//阻塞等待输入 当count=0 说明连接关闭  
  296.                 if (count == 0)  
  297.                 {  
  298.                     dicConnSocket[clineteEndPoint].Close();  
  299.                     messageShow(clineteEndPoint + downLine);  
  300.                     RemoveClient(clineteEndPoint);  
  301.                 }  
  302.                 dicListTimeConnSocket[clineteEndPoint] = DateTime.Now;//有消息传入  
  303.                 #region 协议解析  
  304.                 string ntnt = Encoding.UTF8.GetString(buffer, 0, 4);  
  305.                 if (ntnt != "NTNT")//不是心跳报就显示  
  306.                 {  
  307.                     string msg = Encoding.UTF8.GetString(buffer, 0, count);  
  308.                     messageShow(clineteEndPoint + " : \r\n      " + msg);  
  309.                 }  
  310.                 #endregion  
  311.                 else  
  312.                 {  
  313.                     lock (o)  
  314.                     {  
  315.                         List<Socket> listSendConnSocket = new List<Socket>();  
  316.                         listSendConnSocket.Add(dicConnSocket[clineteEndPoint]);  
  317.                         SendStreamFunction(listSendConnSocket, 3, modelSever);  
  318.                         listSendConnSocket.Clear();  
  319.                     }  
  320.                 }  
  321.             }  
  322.         }  
  323.         #endregion  
  324.  
  325.         #region 发送方法+public void SendStreamFunction(List<Socket> listSendConnSocket, int flag, Model model)  
  326.         /// <summary>  
  327.         /// 发送方法  
  328.         /// </summary>  
  329.         /// <param name="listSendConnSocket"></param>  
  330.         /// <param name="flag"></param>  
  331.         /// <param name="model"></param>  
  332.         public void SendStreamFunction(List<Socket> listSendConnSocket, int flag, Model model, params byte[] buffersend)  
  333.         {  
  334.             if (listSendConnSocket.Count > 0)  
  335.             {  
  336.                 List<byte> list = new List<byte>();  
  337.                 if (flag == 0)  
  338.                 {  
  339.                     byte[] buffer = new byte[5 * 1024 * 1024];  
  340.                     buffer = Encoding.UTF8.GetBytes(model.TxtMsg);  
  341.                     list.Add(0);//协议 0 文字  
  342.                     list.AddRange(buffer);  
  343.                 }  
  344.                 else if (flag == 1)  
  345.                 {  
  346.                     if (model.TxtPath != null)  
  347.                     {  
  348.                         using (FileStream fs = new FileStream(model.TxtPath, FileMode.Open, FileAccess.Read))  
  349.                         {  
  350.                             byte[] buffer = new byte[fs.Length];  
  351.                             fs.Read(buffer, 0, buffer.Length);  
  352.                             list.Add(1);//协议 1 文件  
  353.                             list.AddRange(buffer);  
  354.                         }  
  355.                     }  
  356.                 }  
  357.                 else if (flag == 2)  
  358.                 {  
  359.                     list.Add(2);  
  360.                 }  
  361.                 else if (flag == 3)//没有收到任何通信的协议 一定时间  协议3  
  362.                 {  
  363.                     byte[] buffer = Encoding.UTF8.GetBytes("ATAT");//NTNT心跳报  
  364.                     list.Add(3);  
  365.                     list.AddRange(buffer);  
  366.                 }  
  367.                 else if (flag == 4)  
  368.                 {  
  369.                     if (buffersend != null)  
  370.                     {  
  371.                         list.AddRange(buffersend);  
  372.                     }  
  373.                 }  
  374.                 foreach (Socket item in listSendConnSocket)  
  375.                 {  
  376.                     item.Send(list.ToArray());  
  377.                 }  
  378.             }  
  379.   
  380.         }  
  381.         #endregion  
  382.  
  383.         #region 定时检测方法+public  void Timer()  
  384.         /// <summary>  
  385.         /// 定时检测通信状态  
  386.         /// </summary>  
  387.         public void Timer()  
  388.         {  
  389.             int index = 0;  
  390.             Dictionary<intstring> dic = new Dictionary<intstring>();  
  391.             foreach (KeyValuePair<string, DateTime> item in dicListTimeConnSocket)  
  392.             {  
  393.                 dic.Add(index, item.Key);  
  394.                 index++;  
  395.             }  
  396.             DateTime timeNow = DateTime.Now;  
  397.             for (int i = 0; i < dicListTimeConnSocket.Count; i++)  
  398.             {  
  399.                 if (timeNow.Second - dicListTimeConnSocket[dic[i]].Second > 3)  
  400.                 {  
  401.                     RemoveClient(dic[i]);  
  402.                 }  
  403.             }  
  404.   
  405.         }  
  406.         #endregion  
  407.  
  408.         #region 客户端在服务器注册+public void RegisterClientAtSever(string endPoint, Thread threadMsg, Socket connSocket)  
  409.         /// <summary>  
  410.         /// 客户端注册  
  411.         /// </summary>  
  412.         /// <param name="endPoint">客户端地址</param>  
  413.         /// <param name="threadMsg">通信线程</param>  
  414.         /// <param name="connSocket">通信Socket</param>  
  415.         public void RegisterClientAtSever(string endPoint, Thread threadMsg, Socket connSocket)  
  416.         {  
  417.             dicThreadMsg.Add(endPoint, threadMsg);  
  418.             dicConnSocket.Add(endPoint, connSocket);  
  419.             modelSever.ClientEndPoint = endPoint;  
  420.             if (registerClientIP != null)  
  421.             {  
  422.                 registerClientIP(endPoint);//注册显示到 用户UI上 通过委托 registerClientIP  
  423.             }  
  424.         }  
  425.         #endregion  
  426.         #region 从服务器注销客户端连接+RemoveClient(string clinetEndPoint)  
  427.         /// <summary>  
  428.         /// 从服务器注销客户端连接  
  429.         /// </summary>  
  430.         /// <param name="clinetEndPoint"></param>  
  431.         public void RemoveClient(string clinetEndPoint)  
  432.         {  
  433.             KillClient(clinetEndPoint);  
  434.             dicThreadMsg.Remove(clinetEndPoint);  
  435.             dicConnSocket.Remove(clinetEndPoint);  
  436.             dicListTimeConnSocket.Remove(clinetEndPoint);  
  437.             if (removeClientIPFromUI != null)  
  438.             {  
  439.                 removeClientIPFromUI(clinetEndPoint);  
  440.             }  
  441.         }  
  442.         #endregion  
  443.         #region 终止客户端通信+public void KillClient(string clinetEndPoint)  
  444.         /// <summary>  
  445.         /// 终止客户端通信  
  446.         /// </summary>  
  447.         /// <param name="clinetEndPoint"></param>  
  448.         public void KillClient(string clinetEndPoint)  
  449.         {  
  450.             if (dicConnSocket[clinetEndPoint].Connected)  
  451.             {  
  452.                 dicConnSocket[clinetEndPoint].Shutdown(SocketShutdown.Both);  
  453.             }  
  454.             dicConnSocket[clinetEndPoint].Close();  
  455.             dicThreadMsg[clinetEndPoint].Abort();  
  456.         }  
  457.         #endregion  
  458.     }  
  459. }  

ServerWinform:

[csharp]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Threading;  
  4. using System.Windows.Forms;  
  5. using ServerChatClass;  
  6.   
  7. namespace ChatServer  
  8. {  
  9.     public partial class ServerChar : Form  
  10.     {  
  11.         public ServerChar()  
  12.         {  
  13.             InitializeComponent();  
  14.             Control.CheckForIllegalCrossThreadCalls = false;  
  15.         }  
  16.   
  17.         //Socket connSocket;//通信socket  
  18.         //  Thread thmsg;//接收消息 线程  
  19.   
  20.         ServerChatClass.SeverChar severchar;  
  21.         Model model = new Model();  
  22.   
  23.         private void btnStart_Click(object sender, EventArgs e)  
  24.         {  
  25.             bool enable;  
  26.             model.TxtServer = txtServer.Text;  
  27.             model.TxtPort = txtPort.Text;  
  28.             severchar = new SeverChar("开始监听",model, ShowLog, add, RemoveControl, "掉线",out enable);  
  29.             if (enable)  
  30.             {  
  31.                 btnStart.Enabled = false;  
  32.                 timer1.Start();  
  33.             }  
  34.             else  
  35.             {  
  36.                 btnStart.Enabled = true;  
  37.             }  
  38.         }  
  39.         void add(string clinetIP)  
  40.         {  
  41.             listIp.Items.Add(clinetIP);  
  42.             cboUsers.Items.Add(clinetIP);  
  43.         }  
  44.         public void ShowLog(string msg)  
  45.         {  
  46.             txtLog.AppendText(msg + "\r\n");  
  47.         }  
  48.         #region 发送  
  49.         private void Send(object sender, EventArgs e)  
  50.         {  
  51.             int flag = 0;  
  52.             Button btn = sender as Button;  
  53.             if (btn.Text == "发送消息")  
  54.             {  
  55.                 model.TxtMsg = txtMsg.Text;  
  56.                 flag = 0;  
  57.             }  
  58.             else if (btn.Text == "发送文件")  
  59.             {  
  60.                 model.TxtPath = txtPath.Text;  
  61.                 flag = 1;  
  62.             }  
  63.             else if (btn.Text == "震动")  
  64.             {  
  65.                 flag = 2;  
  66.             }  
  67.             severchar.SendStreamFunction(severchar.listSendConnSocket, flag, model);  
  68.         }  
  69.         //private void SendMsg(object sender, EventArgs e)  
  70.         //{  
  71.   
  72.         //}  
  73.         //private void btnSendFile_Click(object sender, EventArgs e)  
  74.         //{  
  75.         //    model.TxtPath = txtPath.Text;  
  76.         //    severchar.SendStreamFunction(severchar.listSendConnSocket, 1, model);  
  77.         //}  
  78.         //private void btnZD_Click(object sender, EventArgs e)  
  79.         //{  
  80.         //    severchar.SendStreamFunction(severchar.listSendConnSocket, 2, model);  
  81.         //}  
  82.         #endregion  
  83.         private void btnSelect_Click(object sender, EventArgs e)  
  84.         {  
  85.             OpenFileDialog open = new OpenFileDialog();  
  86.             if (open.ShowDialog() == System.Windows.Forms.DialogResult.OK)  
  87.             {  
  88.                 txtPath.Text = open.FileName;  
  89.             }  
  90.         }  
  91.         private void DownLine_Click(object sender, EventArgs e)  
  92.         {  
  93.             for (int i = 0; i < listIp.SelectedItems.Count; i++)  
  94.             {  
  95.                 string clinetIP = listIp.SelectedItems[i].ToString();  
  96.                 severchar.RemoveClient(clinetIP);  
  97.             }  
  98.   
  99.         }  
  100.         private void RemoveControl(string clinetIP)  
  101.         {  
  102.             cboUsers.Items.Remove(clinetIP);  
  103.             listIp.Items.Remove(clinetIP);  
  104.         }  
  105.         private void listIp_SelectedIndexChanged(object sender, EventArgs e)  
  106.         {  
  107.             severchar.listSendConnSocket.Clear();  
  108.             if (listIp.SelectedItems.Count == 1)  
  109.             {  
  110.                 cboUsers.SelectedIndex = listIp.SelectedIndex;  
  111.             }  
  112.             foreach (string item in listIp.SelectedItems)  
  113.             {  
  114.                 severchar.listSendConnSocket.Add(severchar.dicConnSocket[item]);  
  115.             }  
  116.         }  
  117.         private void Server_FormClosing(object sender, FormClosingEventArgs e)  
  118.         {  
  119.             if (severchar.dicThreadMsg.Count > 0)  
  120.             {  
  121.                 int index = 0;  
  122.                 Dictionary<intstring> dic = new Dictionary<intstring>();  
  123.                 foreach (KeyValuePair<string, Thread> item in severchar.dicThreadMsg)  
  124.                 {  
  125.                     dic.Add(index, item.Key);  
  126.                     index++;  
  127.                 }  
  128.                 DateTime timeNow = DateTime.Now;  
  129.                 for (int i = 0; i < severchar.dicThreadMsg.Count; i++)  
  130.                 {  
  131.                     severchar.RemoveClient(dic[i]);                  
  132.                 }  
  133.             }  
  134.         }  
  135.         private void timer1_Tick(object sender, EventArgs e)  
  136.         {  
  137.         if(  severchar.dicListTimeConnSocket.Count>0)  
  138.         {  
  139.             severchar.Timer();  
  140.         }        
  141.         }  
  142.     }  
  143. }  


下载:http://download.csdn.net/detail/s10141303/6675157

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值