[unity3d]unity聊天功能

简介: 感觉之前的聊天功能可能有一些缺陷,今天收到书华兄的启发,发表一些感慨,C# .net高手跟新手的区别就是,新手仅仅满足功能上的实现,而很少去考虑性能上的问题,比如高并发怎么处理,打个比方,新手做完聊天功能之后,会沾沾自喜,而不考虑最大客户连接有多少,做个实验,...

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

unity客户端:

UI:

using UnityEngine;
using System.Collections;

public class chart : MonoBehaviour {

	string txtmsg = "";
	public string txtServer = "192.168.1.24";
	string txtLog = "";
	public string txtPort = "50000";
	ClientLibrary.Client client;
	ClientLibrary.Model model = new ClientLibrary.Model();
	// Use this for initialization
	void Start () {
	
	}

	bool flag = true;
	// Update is called once per frame
	void Update () {
		if(client.HeartDataSend()!=1)
		{
			SetTxt("请检查网络你已经掉线,可能原因服务器出错,请重新连接");
			client.KillSocket();
			flag = false;
		}
	}

	void OnGUI()
	{
		txtServer = GUI.TextField(new Rect(10f,20f,100f,20f),txtServer);
		txtLog = GUI.TextField (new Rect(50f,40f,200f,200f),txtLog);
		if(GUI.Button(new Rect(120f,20f,50f,20f),"start")&&flag)
		{
			model.TxtServer = txtServer;
			model.TxtPort = txtPort;
			bool enable;
			client = new ClientLibrary.Client(model,SetTxt,out enable);
			if(enable)
			{
				//txtLog = "123";
			}
			else
			{
				//txtLog = "no";
			}
			flag = false;
		}
	}
	void SetTxt(string msg)
	{
		txtLog+=msg+"\r\n";
	}
}

ChatClient:

using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace ClientLibrary
{
    #region 委托
    /// <summary>
    /// 信息显示委托
    /// </summary>
    /// <param name="msg">需要打印到前台的信息</param>
    public delegate void deMessageShow(string msg);
    /// <summary>
    /// 文件保存委托
    /// </summary>
    /// <param name="buffer">保存的文件数据</param>
    /// <param name="count">文件大小</param>
    /// <returns></returns>
    public delegate bool deGetFileStream(byte[] buffer,int count);
    /// <summary>
    /// 客户端震动 委托
    /// </summary>
    public delegate void deZD();
    #endregion
    /// <summary>
    /// 客户端实体类
    /// </summary>
    public class Model
    {
        private string txtMsg;

        public string TxtMsg
        {
            get { return txtMsg; }
            set { txtMsg = value; }
        }
        private string txtPort;

        public string TxtPort
        {
            get { return txtPort; }
            set { txtPort = value; }
        }
       private string txtServer;

        public string TxtServer
        {
            get { return txtServer; }
            set { txtServer = value; }
        }
    }
    /// <summary>
    /// 客户端方法类
    /// </summary>
    public class Client
    {
        public Client(Model model,deMessageShow messageShowFun,out bool enable)
        {
            messageShow = messageShowFun;
            lastTimeRecive = DateTime.Now;
            if (CreateClientSocket(model)) //创建Socket
            {
                enable = true;
                return;
            }
            enable = false;     
        }
        public Client(Model model, deMessageShow message, deGetFileStream saveFileFun, out bool enable)
        {
            messageShow = message;
            getFileStream = saveFileFun;
            lastTimeRecive = DateTime.Now;
             if (CreateClientSocket(model))//创建Socket
            {
                enable = true;
                return;
            }
             enable = false;
        }
        public Client(Model model, deMessageShow message, deGetFileStream saveFileFun, deZD zdFun, out bool enable)
        {
            messageShow = message;
            getFileStream = saveFileFun;
            lastTimeRecive = DateTime.Now;
              if (!CreateClientSocket(model)) //创建Socket
            {
                enable = true;
                return;
            }
              enable = false;
        }
        Model model = new Model();
        /// <summary>
        ///  通信Scoket
        /// </summary>
        Socket connSocket;
        /// <summary>
        /// 通信线程
        /// </summary>
        Thread thmsg;
        /// <summary>
        /// 最后一次接受数据时间
        /// </summary>
        public DateTime lastTimeRecive;
        /// <summary>
        /// 最后一次发送数据时间
        /// </summary>
        public DateTime lastTimeSend;
        #region 声明委托
     public   deMessageShow messageShow;
      public  deGetFileStream getFileStream;
     public   deZD zD;
        #endregion

        /// <summary>
        /// 创建客户端Socket
        /// </summary>
        /// <param name="ModelUI"></param>
        /// <returns>创建状态</returns>
        public bool CreateClientSocket(Model ModelUI)
        {
            model = ModelUI;
            bool enabel = false; 
            //服务器IP
            IPAddress ipServer = IPAddress.Parse(model.TxtServer);
            //创建 终端地址
            IPEndPoint endPointServer = new IPEndPoint(ipServer, int.Parse(model.TxtPort));
            //创建 连接socket connSocket
           connSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                connSocket.Connect(endPointServer);
                messageShow("登陆成功");
                #region  创建接受信息的线程
                thmsg = new Thread(ReciveMsg);
                thmsg.IsBackground = true;
                thmsg.Start();
                #endregion
            }
            catch (Exception ex)
            {
                messageShow(ex.Message);
               enabel= true;
            }
            return enabel;
        }

        /// <summary>
        /// 信息接收
        /// </summary>
        private void ReciveMsg()
        {
            //0 文字 1 文件 2 震动
            byte[] buffer = new byte[5 * 1024 * 1024];
            while (true)
            {
                int count = connSocket.Receive(buffer);
                int flag = buffer[0];
                if (count == 0)
                {
                    connSocket.Close();
                    messageShow("你掉线或者服务器关系");
                    break;
                }
                Recive(buffer, count, flag);
            }
        }

        #region 必要方法
        #region 接收+Recive(byte[] buffer, int count,int flag)
        /// <summary>
        /// 处理接受的信息
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="count"></param>
        /// <param name="flag"></param>
        private void Recive(byte[] buffer, int count, int flag)
        {
            if (flag == 0)
            {
                #region flag=0 文字信息
                string msg = Encoding.UTF8.GetString(buffer, 1, count - 1);
                messageShow("服务器 : " + msg);
                #endregion
            }
            else if (flag == 1)
            {
                #region flag=1 传送文件
                if (getFileStream(buffer,count))
                {
                    messageShow("接受完成");
                }           
                #endregion
            }
            else if (flag == 2)
            {
                #region flag=2 震动
                zD();
                #endregion
            }
            else if (flag == 3)
            {
                string atat=Encoding.UTF8.GetString(buffer,1,count-1);
                if (atat == "ATAT")
                {
                    lastTimeRecive = DateTime.Now;
                }
            }
        }


        #endregion
        /// <summary>
        /// 发送心跳包
        /// </summary>
        /// <returns>发送状态</returns>
        public int HeartDataSend()
        {
            lastTimeSend = DateTime.Now;
            if (DateTime.Now.Second - lastTimeRecive.Second > 3)
            {
                return 3;
            }
            if (connSocket != null && connSocket.Connected)
            {
                try
                {
                    byte[] buffer = Encoding.UTF8.GetBytes("NTNT");
                    connSocket.Send(buffer);
                    lastTimeRecive = DateTime.Now;
                    return 1;
                }
                catch (Exception ex)
                {
                   // messageShow(ex.Message);
                    return 2;
                }
            }
            return 1;
        }
        /// <summary>
        /// 数据发送
        /// </summary>
        /// <returns></returns>
        public bool Send()
        {
            if (connSocket != null && connSocket.Connected)
            {
                try
                {
                    byte[] buffer = new byte[1024 * 1024 * 5];
                    buffer = Encoding.UTF8.GetBytes(model.TxtMsg);
                    connSocket.Send(buffer);
                    lastTimeRecive = DateTime.Now;
                    return true;
                }
                catch (Exception ex)
                {
                    messageShow(ex.Message);
                    return false;
                }
            }
            return false;
        }

        /// <summary>
        /// 终止连接
        /// </summary>
        public void KillSocket()
        {
            if (thmsg != null)
            {
                thmsg.Abort();
            }
            if (connSocket != null && connSocket.Connected)
            {
                connSocket.Shutdown(SocketShutdown.Both);
                connSocket.Close();
            }
        }
        #endregion
    }
}

服务器端:

Server:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace ServerChatClass
{
    #region 委托
    /// <summary>
    /// 信息显示委托
    /// </summary>
    /// <param name="msg">需要打印到前台的信息</param>
    public delegate void deMessageShow(string msg);
    /// <summary>
    /// 注册客户端ednpoing和Socket,Thread
    /// </summary>
    /// <param name="endpoing">注册地址</param>
    public delegate void deRegisterClientIP(string endpoing);
    /// <summary>
    /// 从UI上移除客户端显示
    /// </summary>
    /// <param name="endpoing">客户端地址或者名称</param>
    public delegate void deRemoveClientIPFromUI(string endpoing);
    #endregion
    /// <summary>
    /// 实体类
    /// </summary>
    public class Model
    {
        private string txtMsg;
        private string txtPath;

        private string txtLog;
        private string txtServer;
        private string txtPort;

        private string clientEndPoint;
        /// <summary>
        /// 客户端地址
        /// </summary>
        public string ClientEndPoint
        {
            get { return clientEndPoint; }
            set { clientEndPoint = value; }
        }
        /// <summary>
        /// 端口
        /// </summary>
        public string TxtPort
        {
            get { return txtPort; }
            set { txtPort = value; }
        }
        /// <summary>
        /// IP
        /// </summary>
        public string TxtServer
        {
            get { return txtServer; }
            set { txtServer = value; }
        }
        /// <summary>
        /// 日志
        /// </summary>
        public string TxtLog
        {
            get { return txtLog; }
            set { txtLog = value; }
        }
        /// <summary>
        /// 文件地址
        /// </summary>
        public string TxtPath
        {
            get { return txtPath; }
            set { txtPath = value; }
        }
        /// <summary>
        /// 消息文字发送
        /// </summary>
        public string TxtMsg
        {
            get { return txtMsg; }
            set { txtMsg = value; }
        }

    }
    public class Request
    {
        public Request(string msg)
        {
            if (msg.Length < 100)
            { return; }
            try
            {
                string[] lines = msg.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
                string firstLine = lines[0];
                string[] array = firstLine.Split(' ');
                method = array[0];
                url = array[1];
            }
            catch (Exception)
            {

            }

        }
        private string method;
        public string Method
        {
            get { return method; }
            set { method = value; }
        }
        private string url;
        public string Url
        {
            get { return url; }
            set { url = value; }
        }
    }
    public class SeverChar
    {

        #region 客户机注册字典
        /// <summary>
        /// 客户端地址clientIP和对应最后一次通信时间
        /// </summary>
        public Dictionary<string, DateTime> dicListTimeConnSocket = new Dictionary<string, DateTime>();
        /// <summary>
        /// 客户端地址clinetIP和对应的通信Socket
        /// </summary>
        public Dictionary<string, Socket> dicConnSocket = new Dictionary<string, Socket>();
        /// <summary>
        /// 客户端地址clientIP和对应通信线程ThreadMsg
        /// </summary>
        public Dictionary<string, Thread> dicThreadMsg = new Dictionary<string, Thread>();
        #endregion
        #region 委托声明
        /// <summary>
        /// 消息显示
        /// </summary>
        public deMessageShow messageShow;
        /// <summary>
        /// 注册客户机
        /// </summary>
        public deRegisterClientIP registerClientIP;
        /// <summary>
        /// 从UI上移除客户端显示
        /// </summary>
        public deRemoveClientIPFromUI removeClientIPFromUI;
        #endregion
        /// <summary>
        /// 初始化程序
        /// </summary>
        /// <param name="downline">掉线信息</param>

        public SeverChar(string msg,Model model, deMessageShow messageShowFun, string downline, out bool enable)
        {
            messageShow = messageShowFun;
            if (CreateServerMonitorSorcket(model,msg)) //创建Socket
            {
                enable = true;
            }
            else
            {
                enable = false;
            }
        }
        public SeverChar(string msg,Model model, deMessageShow messageShowFun,deRegisterClientIP registerClientIPFun ,string downline, out bool enable)
        {
            registerClientIP = registerClientIPFun;
            messageShow = messageShowFun;
            if (CreateServerMonitorSorcket(model, msg))//创建Socket
            {
                enable = true;
            }
            else
            {
                enable = false;
            }
        }
        public SeverChar(string msg,Model model, deMessageShow messageShowFun, deRegisterClientIP registerClientIPFun, deRemoveClientIPFromUI removerClientIPFormUIFun,string downline, out bool enable)
        {
            removeClientIPFromUI = removerClientIPFormUIFun;
            registerClientIP = registerClientIPFun;
            messageShow = messageShowFun;
            if (CreateServerMonitorSorcket(model, msg)) //创建Socket
            {
                enable = true;
            }
            else
            {
                enable=false;
            }
        }
        public SeverChar(string downline)
        {
            downLine = downline;
        }
        /// <summary>
        /// 需要发送请求的通信Socket
        /// </summary>
        public List<Socket> listSendConnSocket = new List<Socket>();
        /// <summary>
        /// 掉线信息提示
        /// </summary>
        public string downLine;
        Socket socketServer;//监听socket
        Model modelSever = new Model();
        object o = new object();

        #region 创建监听的socket socketServer+public bool CreateServerMonitorSorcket(Model model, string msg)
        /// <summary>
        /// 服务器创建监听的socket socketServer
        /// </summary>
        /// <param name="model">监听实体,包含监听端口和IP</param>
        /// <param name="msg">监听成功后显示的信息</param>
        /// <returns></returns>
        public bool CreateServerMonitorSorcket(Model model, string msg)
        {
            modelSever = model;
            bool enable;
            Socket socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            #  region 其他测试
            //IPHostEntry host = new IPHostEntry();
            //host.
            #endregion
            //Ip地址
            IPAddress ipServer = IPAddress.Parse(model.TxtServer);
            //ip地址和端口
            IPEndPoint endPointServer = new IPEndPoint(ipServer, int.Parse(model.TxtPort));
            try
            {
                //绑定网络端点
                socketServer.Bind(endPointServer);
                //设置排队长度
                socketServer.Listen(10);
                messageShow(msg);
                #region 用连接连接线程ThreadConnSockt  创建通信Socket 防止阻塞卡死+Listen(object)
                Thread threadConnSocket = new Thread(Listen);
                threadConnSocket.Name = "conn";
                threadConnSocket.IsBackground = true;
                threadConnSocket.Start(socketServer);
                #endregion
                enable = true;
            }
            catch (Exception ex)
            {
                messageShow(ex.Message);
                enable = false;
            }
            return enable;
        }
        #endregion

        #region 创建服务端通信Socket  connSocket单线程会阻塞窗体运行+Listen(object)
        /// <summary>
        /// 创建通信Socket
        /// </summary>
        /// <param name="socket"></param>
        public void Listen(object socket)
        {
            socketServer = socket as Socket;
            while (true)
            {
                Socket connSocket = socketServer.Accept();//阻塞等待 客户端连接
                string clinetEndPing = connSocket.RemoteEndPoint.ToString();//获取客户端通信地址
                messageShow(clinetEndPing+"登陆");
                #region 新建通信监听线程threadMsg 接收客户端发送过来的信息
                Thread threadMsg = new Thread(ReciveMsg);             
                threadMsg.Name = "msg";
                threadMsg.IsBackground = true;
                threadMsg.Start(connSocket);
                RegisterClientAtSever(clinetEndPing, threadMsg, connSocket);
                #endregion
            }
        }
        #endregion
        #region 接收客户端发送的信息 ReciveMsg(object socket)
        /// <summary>
        /// 接收客户端发送的信息 方法
        /// </summary>
        /// <param name="socket">发送信息的socket</param>
        public void ReciveMsg(object socket)
        {
            Socket connSocket = socket as Socket;
            string clineteEndPoint = connSocket.RemoteEndPoint.ToString();
            byte[] buffer = new byte[1024 * 1024 * 5];
            while (true)
            {
                int count = connSocket.Receive(buffer);//阻塞等待输入 当count=0 说明连接关闭
                if (count == 0)
                {
                    dicConnSocket[clineteEndPoint].Close();
                    messageShow(clineteEndPoint + downLine);
                    RemoveClient(clineteEndPoint);
                }
                dicListTimeConnSocket[clineteEndPoint] = DateTime.Now;//有消息传入
                #region 协议解析
                string ntnt = Encoding.UTF8.GetString(buffer, 0, 4);
                if (ntnt != "NTNT")//不是心跳报就显示
                {
                    string msg = Encoding.UTF8.GetString(buffer, 0, count);
                    messageShow(clineteEndPoint + " : \r\n      " + msg);
                }
                #endregion
                else
                {
                    lock (o)
                    {
                        List<Socket> listSendConnSocket = new List<Socket>();
                        listSendConnSocket.Add(dicConnSocket[clineteEndPoint]);
                        SendStreamFunction(listSendConnSocket, 3, modelSever);
                        listSendConnSocket.Clear();
                    }
                }
            }
        }
        #endregion

        #region 发送方法+public void SendStreamFunction(List<Socket> listSendConnSocket, int flag, Model model)
        /// <summary>
        /// 发送方法
        /// </summary>
        /// <param name="listSendConnSocket"></param>
        /// <param name="flag"></param>
        /// <param name="model"></param>
        public void SendStreamFunction(List<Socket> listSendConnSocket, int flag, Model model, params byte[] buffersend)
        {
            if (listSendConnSocket.Count > 0)
            {
                List<byte> list = new List<byte>();
                if (flag == 0)
                {
                    byte[] buffer = new byte[5 * 1024 * 1024];
                    buffer = Encoding.UTF8.GetBytes(model.TxtMsg);
                    list.Add(0);//协议 0 文字
                    list.AddRange(buffer);
                }
                else if (flag == 1)
                {
                    if (model.TxtPath != null)
                    {
                        using (FileStream fs = new FileStream(model.TxtPath, FileMode.Open, FileAccess.Read))
                        {
                            byte[] buffer = new byte[fs.Length];
                            fs.Read(buffer, 0, buffer.Length);
                            list.Add(1);//协议 1 文件
                            list.AddRange(buffer);
                        }
                    }
                }
                else if (flag == 2)
                {
                    list.Add(2);
                }
                else if (flag == 3)//没有收到任何通信的协议 一定时间  协议3
                {
                    byte[] buffer = Encoding.UTF8.GetBytes("ATAT");//NTNT心跳报
                    list.Add(3);
                    list.AddRange(buffer);
                }
                else if (flag == 4)
                {
                    if (buffersend != null)
                    {
                        list.AddRange(buffersend);
                    }
                }
                foreach (Socket item in listSendConnSocket)
                {
                    item.Send(list.ToArray());
                }
            }

        }
        #endregion

        #region 定时检测方法+public  void Timer()
        /// <summary>
        /// 定时检测通信状态
        /// </summary>
        public void Timer()
        {
            int index = 0;
            Dictionary<int, string> dic = new Dictionary<int, string>();
            foreach (KeyValuePair<string, DateTime> item in dicListTimeConnSocket)
            {
                dic.Add(index, item.Key);
                index++;
            }
            DateTime timeNow = DateTime.Now;
            for (int i = 0; i < dicListTimeConnSocket.Count; i++)
            {
                if (timeNow.Second - dicListTimeConnSocket[dic[i]].Second > 3)
                {
                    RemoveClient(dic[i]);
                }
            }

        }
        #endregion

        #region 客户端在服务器注册+public void RegisterClientAtSever(string endPoint, Thread threadMsg, Socket connSocket)
        /// <summary>
        /// 客户端注册
        /// </summary>
        /// <param name="endPoint">客户端地址</param>
        /// <param name="threadMsg">通信线程</param>
        /// <param name="connSocket">通信Socket</param>
        public void RegisterClientAtSever(string endPoint, Thread threadMsg, Socket connSocket)
        {
            dicThreadMsg.Add(endPoint, threadMsg);
            dicConnSocket.Add(endPoint, connSocket);
            modelSever.ClientEndPoint = endPoint;
            if (registerClientIP != null)
            {
                registerClientIP(endPoint);//注册显示到 用户UI上 通过委托 registerClientIP
            }
        }
        #endregion
        #region 从服务器注销客户端连接+RemoveClient(string clinetEndPoint)
        /// <summary>
        /// 从服务器注销客户端连接
        /// </summary>
        /// <param name="clinetEndPoint"></param>
        public void RemoveClient(string clinetEndPoint)
        {
            KillClient(clinetEndPoint);
            dicThreadMsg.Remove(clinetEndPoint);
            dicConnSocket.Remove(clinetEndPoint);
            dicListTimeConnSocket.Remove(clinetEndPoint);
            if (removeClientIPFromUI != null)
            {
                removeClientIPFromUI(clinetEndPoint);
            }
        }
        #endregion
        #region 终止客户端通信+public void KillClient(string clinetEndPoint)
        /// <summary>
        /// 终止客户端通信
        /// </summary>
        /// <param name="clinetEndPoint"></param>
        public void KillClient(string clinetEndPoint)
        {
            if (dicConnSocket[clinetEndPoint].Connected)
            {
                dicConnSocket[clinetEndPoint].Shutdown(SocketShutdown.Both);
            }
            dicConnSocket[clinetEndPoint].Close();
            dicThreadMsg[clinetEndPoint].Abort();
        }
        #endregion
    }
}

ServerWinform:

using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Forms;
using ServerChatClass;

namespace ChatServer
{
    public partial class ServerChar : Form
    {
        public ServerChar()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        //Socket connSocket;//通信socket
        //  Thread thmsg;//接收消息 线程

        ServerChatClass.SeverChar severchar;
        Model model = new Model();

        private void btnStart_Click(object sender, EventArgs e)
        {
            bool enable;
            model.TxtServer = txtServer.Text;
            model.TxtPort = txtPort.Text;
            severchar = new SeverChar("开始监听",model, ShowLog, add, RemoveControl, "掉线",out enable);
            if (enable)
            {
                btnStart.Enabled = false;
                timer1.Start();
            }
            else
            {
                btnStart.Enabled = true;
            }
        }
        void add(string clinetIP)
        {
            listIp.Items.Add(clinetIP);
            cboUsers.Items.Add(clinetIP);
        }
        public void ShowLog(string msg)
        {
            txtLog.AppendText(msg + "\r\n");
        }
        #region 发送
        private void Send(object sender, EventArgs e)
        {
            int flag = 0;
            Button btn = sender as Button;
            if (btn.Text == "发送消息")
            {
                model.TxtMsg = txtMsg.Text;
                flag = 0;
            }
            else if (btn.Text == "发送文件")
            {
                model.TxtPath = txtPath.Text;
                flag = 1;
            }
            else if (btn.Text == "震动")
            {
                flag = 2;
            }
            severchar.SendStreamFunction(severchar.listSendConnSocket, flag, model);
        }
        //private void SendMsg(object sender, EventArgs e)
        //{

        //}
        //private void btnSendFile_Click(object sender, EventArgs e)
        //{
        //    model.TxtPath = txtPath.Text;
        //    severchar.SendStreamFunction(severchar.listSendConnSocket, 1, model);
        //}
        //private void btnZD_Click(object sender, EventArgs e)
        //{
        //    severchar.SendStreamFunction(severchar.listSendConnSocket, 2, model);
        //}
        #endregion
        private void btnSelect_Click(object sender, EventArgs e)
        {
            OpenFileDialog open = new OpenFileDialog();
            if (open.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtPath.Text = open.FileName;
            }
        }
        private void DownLine_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < listIp.SelectedItems.Count; i++)
            {
                string clinetIP = listIp.SelectedItems[i].ToString();
                severchar.RemoveClient(clinetIP);
            }

        }
        private void RemoveControl(string clinetIP)
        {
            cboUsers.Items.Remove(clinetIP);
            listIp.Items.Remove(clinetIP);
        }
        private void listIp_SelectedIndexChanged(object sender, EventArgs e)
        {
            severchar.listSendConnSocket.Clear();
            if (listIp.SelectedItems.Count == 1)
            {
                cboUsers.SelectedIndex = listIp.SelectedIndex;
            }
            foreach (string item in listIp.SelectedItems)
            {
                severchar.listSendConnSocket.Add(severchar.dicConnSocket[item]);
            }
        }
        private void Server_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (severchar.dicThreadMsg.Count > 0)
            {
                int index = 0;
                Dictionary<int, string> dic = new Dictionary<int, string>();
                foreach (KeyValuePair<string, Thread> item in severchar.dicThreadMsg)
                {
                    dic.Add(index, item.Key);
                    index++;
                }
                DateTime timeNow = DateTime.Now;
                for (int i = 0; i < severchar.dicThreadMsg.Count; i++)
                {
                    severchar.RemoveClient(dic[i]);                
                }
            }
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
        if(  severchar.dicListTimeConnSocket.Count>0)
        {
            severchar.Timer();
        }      
        }
    }
}


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



==================== 迂者 丁小未 CSDN博客专栏=================

MyBlog:http://blog.csdn.net/dingxiaowei2013              MyQQ:1213250243

MyTel:13262983383 

====================== 相互学习,共同进步 ===================


相关文章
|
JSON 图形学 数据格式
unity使用TextMeshPro实现聊天图文混排
使用unity也能实现qq好友聊天效果
|
5月前
|
C# 图形学
【unity小技巧】Unity音乐和音效管理器
【unity小技巧】Unity音乐和音效管理器
151 0
|
3月前
|
图形学 iOS开发
Unity与IOS⭐最基础的交互演示
Unity与IOS⭐最基础的交互演示
|
5月前
|
图形学
【用unity实现100个游戏之16】Unity中程序化生成的2D地牢4(附项目源码)
【用unity实现100个游戏之16】Unity中程序化生成的2D地牢4(附项目源码)
42 0
|
iOS开发
iOS 常用阅读软件打开书籍的转场动画
iOS 常用阅读软件打开书籍的转场动画
94 0
|
图形学
Unity3D简陋版跑酷游戏
Unity3D简陋版跑酷游戏
Unity3D简陋版跑酷游戏
|
编译器 C# 图形学
unity2020学习(一)界面了解
了解unity游戏引擎开发界面
403 0
unity2020学习(一)界面了解
|
存储 图形学
Unity3D基本入门及功能介绍
第一,界面入门Unity3D 最经典 2 by 3 结构界面,上面呈现了 Unity3D 最为常用的几个面板,下面为各个面板的详细说明。1.Scene【场景面板】:该面板为 Unity3D 的编辑面板;你可以将你所有的模型、灯光、以及其他材质对象拖放到该场景中。
2818 0
|
图形学
Unity等待写入数据
EasyTouch中QuickGesture的用法 本文提供全流程,中文翻译。Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例) ...
968 0
|
前端开发 图形学
Unity 之大屏幕多点触控插件 TouchScript 9.0 入门指南(上)
在端游上大家应该多数都使用过的EasyTouch插件,在EasyTouch 5.0.17 最新版本扩展方法中我有过简单的介绍,今天说一下另一款触摸插件,它非常适合做展示类大屏幕的多点触控TouchScript,在Unity上的AssetStore也是五...
3411 0