using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace StandardLibrary { /// /// TCP服务器类 /// class Tcp_Server { #region 字段声明 /// /// TCP服务器接收到客户端连接请求事件 /// public Action TcpConnectEvent; /// /// TCP服务器接收到客户端发送消息事件 /// public Action TcpReceiveEvent; /// /// 负责监听客户端连接请求的线程 /// private Thread threadWatch = null; /// /// //服务器套接字 /// private Socket socketWatch = null; /// /// //客户端IP与套接字的集合 /// private Dictionary dictSocket = new Dictionary(); /// /// //客户端IP与线程的集合 /// private Dictionary dictThread = new Dictionary(); private string _serverIp = "127.0.0.1"; private int _serverPort = 1234; #endregion public string ServerIp { get { return _serverIp; } set { _serverIp = value; } } public int ServerPort { get { return _serverPort; } set { _serverPort = value; } } /// /// 打开侦听 /// /// 侦听的IP /// 侦听的端口号 public bool OpenTcpListen() { try { socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建负责监听的套接字 IPAddress address = IPAddress.Parse(_serverIp);//获得IP地址 IPEndPoint endPoint = new IPEndPoint(address, _serverPort);//创建包含ip和端口号的网络节点对象 socketWatch.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); socketWatch.Bind(endPoint);//将负责监听的套接字绑定到唯一的ip和端口上 socketWatch.Listen(16);//设置侦听队列的长度,开始侦听 threadWatch = new Thread(WatchConnecting);//创建负责侦听的线程 threadWatch.IsBackground = true;//设置为后台线程 threadWatch.Start();//启动线程 return true; } catch (Exception e) { MessageBox.Show("异常:" + e.Message, "服务器侦听", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); return false; } } /// /// 侦听客户端请求 /// private void WatchConnecting() { while (true) //持续监听客户端的连接请求 { // 开始监听客户端连接请求,Accept方法会阻断当前的线程 Socket sokConnection = socketWatch.Accept(); //一旦监听到一个客户端的请求,就返回一个与该客户端通信的套接字 string ip = sokConnection.RemoteEndPoint.ToString().Split(':')[0]; if (!dictSocket.ContainsKey(ip)) dictSocket.Add(ip, sokConnection);//将客户端的IP对象添加到集合中 else dictSocket[ip] = sokConnection; Thread thr = new Thread(ReceiveMsg);//创建处理客户端连接线程 thr.IsBackground = true;//设置为后台线程 thr.Start(sokConnection);//启动线程 if (!dictThread.ContainsKey(ip)) dictThread.Add(ip, thr); //将新建的线程添加到线程的集合中 else dictThread[ip] = thr; if (TcpConnectEvent != null) TcpConnectEvent(ip, true);//发布客户端连接成功消息 } } /// /// 接收数据处理 /// /// 客户端套接字 private void ReceiveMsg(object sokConnectionparn) { Socket sokClient = sokConnectionparn as Socket;//客户端套接字 string ip = sokClient.RemoteEndPoint.ToString().Split(':')[0]; try { while (true) { byte[] arrMsgRec = new byte[2048 * 1];//定义一个1k字节的接收缓存区 int length = sokClient.Receive(arrMsgRec);//接收数据将数据存入arrMsgRec,返回数据的长度,并阻挡当前线程 if (length > 0)//判断接收到的数据长度,如果大于0则表示数据正常,如果小于或等于0则表示客户端断开连接 { byte[] rec = new byte[length]; Array.Copy(arrMsgRec, rec, length); if (TcpReceiveEvent != null) TcpReceiveEvent(ip, rec);//发布接收客户端消息 } else dictThread[ip].Abort();//释放线程 } } catch (Exception) { if (dictSocket.ContainsKey(ip)) dictSocket.Remove(ip);//从通信套接字集合中删除被中断连接的通信套接字 if (dictThread.ContainsKey(ip)) dictThread.Remove(ip);//从通信线程集合中删除被中断连接的通信线程对象 if (TcpConnectEvent != null) TcpConnectEvent(ip, false);//发布客户端连接断开消息 } } public void CloseTcpConnect(string ip) { if (dictSocket.ContainsKey(ip)) { dictThread[ip].Abort(); dictSocket[ip].Close(); } } public void CloseTcpListen() { //socketWatch.Close(); //socketWatch.Dispose(); //threadWatch.Abort(); } /// /// 发送消息 /// /// 客户端IP地址 /// 数据 public bool SendServerMsg(string IP, string SendData) { try { byte[] sendMsg = Encoding.ASCII.GetBytes(SendData); if (dictSocket.ContainsKey(IP)) dictSocket[IP].Send(sendMsg);//发送数据 return true; } catch { return false; } } /// /// 发送消息 /// /// 客户端IP地址 /// 数据 public bool SendServerMsg(string IP, byte[] SendData) { try { if (dictSocket.ContainsKey(IP)) dictSocket[IP].Send(SendData);//发送数据 return true; } catch { return false; } } } /// /// TCP客户端类 /// class Tcp_Client { /// /// 接收消息事件 /// public event Action TcpReceiveEvent; /// /// 连接状态事件 /// public event Action TcpConnectEvent; /// /// TCP客户端 /// private Socket tcpClient; /// /// 接收消息线程 /// private Thread receiveThread; private string _ip = "127.0.0.1"; private int _port = 8500; /// /// 获取或设置远程服务端IP地址 /// public string IP { get { return _ip; } set { _ip = value; } } /// /// 获取或设置远程服务端端口号 /// public int Port { get { return _port; } set { _port = value; } } /// /// 打开连接 /// /// /// public bool OpenTcpConnect() { IPEndPoint IpEnd = new IPEndPoint(IPAddress.Parse(_ip), _port); tcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { tcpClient.Connect(IpEnd);//发起TCP连接 receiveThread = new Thread(ReceiveMsg);//实例化并启动接受消息线程 receiveThread.IsBackground = true;//设置为后台线程 receiveThread.Start();//启动线程 if (TcpConnectEvent != null) TcpConnectEvent(true);//发布连接成功消息 return true; } catch (Exception e) { if (TcpConnectEvent != null) TcpConnectEvent(false);//发布连接失败消息 return false; } } /// /// 关闭连接 /// public void CloseTcpConnect() { tcpClient.Close();//断开TCP连接 receiveThread.Abort();//销毁接受消息的线程 } /// /// 接收服务端发送的消息 /// public void ReceiveMsg() { try { while (true) { byte[] getData = new byte[2048];//创建接受数据的字节流 int length = tcpClient.Receive(getData, getData.Length, 0); if (length > 0) { byte[] rec = new byte[length]; Array.Copy(getData, rec, length); string getMsg = Encoding.ASCII.GetString(rec);//将字节数组转换成文本形式 if (TcpReceiveEvent != null) TcpReceiveEvent(getMsg); } else receiveThread.Abort();//释放线程 } } catch (Exception e)//检测释放线程异常 { if (TcpConnectEvent != null) TcpConnectEvent(false);//发布连接断开消息 CloseTcpConnect(); } } /// /// 发送消息给服务端 /// /// 数据 public void SendMsg(string msg) { byte[] sendData = Encoding.ASCII.GetBytes(msg);//将要发送的文本转换为字符数组形式 tcpClient.Send(sendData, sendData.Length, 0); } /// /// 发送消息给服务端 /// /// 数据 public void SendMsg(byte[] msg) { tcpClient.Send(msg); } } }