using System; using System.Collections.Generic; using System.Text; using System.Net.Sockets; using System.Net; using System.Threading; using UnityEngine; namespace GeneralTools { public class TCPServer : SocketBase { Dictionary dict = new Dictionary(); Dictionary dictThread = new Dictionary(); Thread threadWatch = null; // 负责监听客户端连接请求的 线程; Socket socketWatch = null; public TCPServer(string ip, int port, int _listenLong = 100) { InitSocket(ip, port, _listenLong); } //初始化 void InitSocket(string ip, int port, int _listenLong) { socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress address = string.IsNullOrEmpty(ip) ? IPAddress.Any : IPAddress.Parse(ip); IPEndPoint endPoint = new IPEndPoint(address, port); try { socketWatch.Bind(endPoint); } catch (SocketException se) { Debug.LogError(se.Message); return; } socketWatch.Listen(_listenLong); threadWatch = new Thread(WatchConnecting); threadWatch.IsBackground = true; threadWatch.Start(); } void WatchConnecting() { while (true) // 持续不断的监听客户端的连接请求; { if (socketClose) return; // 开始监听客户端连接请求,Accept方法会阻断当前的线程; Socket sokConnection = null; try { sokConnection = socketWatch.Accept(); } catch (SocketException) { continue; } if (sokConnection == null) continue; // 一旦监听到一个客户端的请求,就返回一个与该客户端通信的 套接字; // 想列表控件中添加客户端的IP信息 // 将与客户端连接的 套接字 对象添加到集合中; dict.Add(sokConnection.RemoteEndPoint.ToString(), sokConnection); Thread thr = new Thread(RecMsg); thr.IsBackground = true; thr.Start(sokConnection); dictThread.Add(sokConnection.RemoteEndPoint.ToString(), thr); // 将新建的线程 添加 到线程的集合中去。 } } void RecMsg(object sokConnectionparn) { Socket sokClient = sokConnectionparn as Socket; string remoteEndPoint = sokClient.RemoteEndPoint.ToString(); while (true) { if (socketClose) return; byte[] arrMsgRec = new byte[reveiceByteSize]; // 将接受到的数据存入到输入 arrMsgRec中; int length = -1; try { length = sokClient.Receive(arrMsgRec); // 接收数据,并返回数据的长度; } catch (Exception e) { // 从 通信套接字 集合中删除被中断连接的通信套接字; dict.Remove(remoteEndPoint); // 从通信线程集合中删除被中断连接的通信线程对象; dictThread.Remove(remoteEndPoint); // 从列表中移除被中断的连接IP break; } if (length == 0) { // 从 通信套接字 集合中删除被中断连接的通信套接字; dict.Remove(remoteEndPoint); // 从通信线程集合中删除被中断连接的通信线程对象; dictThread.Remove(remoteEndPoint); // 从列表中移除被中断的连接IP break; } //保存接收到的数据 RecordReceiveMsg(arrMsgRec, length, sokClient.LocalEndPoint, sokClient.RemoteEndPoint); } } public override void SendMsg(string strMsg) { byte[] _sendData = String2Bytes(strMsg, encoding); foreach (Socket s in dict.Values) { try { s.Send(_sendData, _sendData.Length, SocketFlags.None); } catch (Exception se) { Debug.LogError(se.Message); } } } public override void SendMsg(byte[] byteMsg) { base.SendMsg(byteMsg); foreach (Socket s in dict.Values) { try { s.Send(byteMsg, byteMsg.Length, SocketFlags.None); } catch (Exception se) { Debug.LogError(se.Message); } } } public override void SendMsg(IPEndPoint remote, string strMsg) { base.SendMsg(remote, strMsg); byte[] _sendData = String2Bytes(strMsg, encoding); string remoteStr = remote.ToString(); if (dict.ContainsKey(remoteStr)) { try { dict[remoteStr].Send(_sendData, _sendData.Length, SocketFlags.None); } catch (Exception se) { Debug.LogError(se.Message); } } } public override void SendMsg(IPEndPoint remote, byte[] byteMsg) { base.SendMsg(remote, byteMsg); string remoteStr = remote.ToString(); if (dict.ContainsKey(remoteStr)) { try { dict[remoteStr].Send(byteMsg, byteMsg.Length, SocketFlags.None); } catch (Exception se) { Debug.LogError(se.Message); } } } //连接关闭 public override void SocketQuit() { base.SocketQuit(); foreach (var dic in dict) { if (dic.Value != null) { dic.Value.Close(); } } foreach (var dic in dictThread) { if (dic.Value != null) { dic.Value.Interrupt(); dic.Value.Abort(); } } if (socketWatch != null) socketWatch.Close(); if (threadWatch != null) { threadWatch.Interrupt(); threadWatch.Abort(); } } } }