using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text.RegularExpressions; namespace HH.WCS.ZhongCeJinTan.device { public class TcpServer { public TcpServer(string ip) { Init(ip); } private void Init(string ip) { //创建一个新的Socket,这里我们使用最常用的基于TCP的Stream Socket(流式套接字) var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { //将该socket绑定到主机上面的某个端口 socket.Bind(new IPEndPoint(IPAddress.Parse(ip), 2024)); Console.WriteLine("开启tcp server 2024"); //启动监听,并且设置一个最大的队列长度 socket.Listen(30); //开始接受客户端连接请求 socket.BeginAccept(new AsyncCallback(ClientAccepted), socket); } catch (Exception e) { Console.WriteLine(e.Message); } } public static Dictionary clients = new Dictionary(); public static Dictionary buffers = new Dictionary(); public static void ClientAccepted(IAsyncResult ar) { var socket = ar.AsyncState as Socket; var client = socket.EndAccept(ar); string remote_ip = ((System.Net.IPEndPoint)client.RemoteEndPoint).Address.ToString(); if (clients.Keys.Contains(remote_ip)) { clients[remote_ip] = client; } else { clients.Add(remote_ip, client); } if (!buffers.Keys.Contains(remote_ip)) { buffers.Add(remote_ip, new byte[1024]); } //给客户端发送一个欢迎消息 //client.Send(Encoding.Unicode.GetBytes("Hi there, I accept you request at " + DateTime.Now.ToString())); Console.WriteLine(remote_ip); try { client.BeginReceive(buffers[remote_ip], 0, buffers[remote_ip].Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), client); } catch (Exception ex) { Console.WriteLine($"【接收客户端的消息异常】:" + ex.Message); } //准备接受下一个客户端请求 socket.BeginAccept(new AsyncCallback(ClientAccepted), socket); } public static void ReceiveMessage(IAsyncResult ar) { try { var socket = ar.AsyncState as Socket; string remote_ip = ((System.Net.IPEndPoint)socket.RemoteEndPoint).Address.ToString(); var length = socket.EndReceive(ar); if (length == 0) { clients.Remove(remote_ip); buffers.Remove(remote_ip); return; } else { if (!clients.Keys.Contains(remote_ip)) { clients.Add(remote_ip, socket); } if (!buffers.Keys.Contains(remote_ip)) { buffers.Add(remote_ip, new byte[1024]); } } try { if (buffers.Keys.Contains(remote_ip)) { //读取出来消息内容 var message = GetHexString(buffers[remote_ip], length);//16 10 Console.WriteLine(message); if (message.Substring(0, 4) == "3f00" && message.Substring(message.Length - 4) == "0d0a") { //消息分割,去重 var list = Regex.Split(message, "0d0a", RegexOptions.IgnoreCase).Distinct().ToList(); foreach (var item in list) { if (!string.IsNullOrEmpty(item)) { string msg = item.Replace(@"0d", "").Replace(@"0a", "").Replace(@"0d0a", "").Trim(); PlcHelper.Receive(remote_ip, msg); } } Array.Clear(buffers[remote_ip], 0, buffers[remote_ip].Length);//清空当前IP Buffer } else { Console.WriteLine($"【TCP信息协议异常】:IP:{remote_ip},MSG:{message}"); } } else { if (!buffers.Keys.Contains(remote_ip)) { buffers.Add(remote_ip, new byte[1024]); } } } catch (Exception ex) { Console.WriteLine($"【处理客户端的消息异常】:" + ex.Message); } //接收下一个消息(因为这是一个递归的调用,所以这样就可以一直接收消息了) socket.BeginReceive(buffers[remote_ip], 0, buffers[remote_ip].Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket); } catch (Exception ex) { Console.WriteLine(ex.Message); } } private static string GetHexString(byte[] buffer, int lenght) { return BitConverter.ToString(buffer, 0, lenght).Replace("-", string.Empty).ToLower(); } public static bool TcpServerSend(string ip, byte[] msg) { if (clients.Keys.Contains(ip)) { var client = clients[ip]; if (client.Connected) { try { client.Send(msg); return true; } catch (SocketException ex) { Console.WriteLine(ex.Message); clients[ip].Close(); clients.Remove(ip); } } else { clients[ip].Close(); clients.Remove(ip); } } else { Console.WriteLine("未找到设备的链接:" + ip); } return false; } } }