using HH.WCS.Mobox3.DoubleCoin.dispatch; using HH.WCS.Mobox3.DoubleCoin.util; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; namespace HH.WCS.Mobox3.DoubleCoin.device { public class TcpServer { public TcpServer(string ip, int port) { Init(ip, port); } private void Init(string ip, int port) { //创建一个新的Socket,这里我们使用最常用的基于TCP的Stream Socket(流式套接字) var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { //将该socket绑定到主机上面的某个端口,端口应该放到配置文件中 socket.Bind(new IPEndPoint(IPAddress.Parse(ip), port)); Console.WriteLine(port); //启动监听,并且设置一个最大的队列长度 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 Dictionary isSend = new Dictionary(); public static Dictionary isCheck = new Dictionary(); public static Dictionary saoMa = 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]); } if (!isSend.Keys.Contains(remote_ip)) { isSend.Add(remote_ip, false); } if (!isCheck.Keys.Contains(remote_ip)) { isCheck.Add(remote_ip, false); } //给客户端发送一个欢迎消息 //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); isSend.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]); } if (!isSend.Keys.Contains(remote_ip)) { isSend.Add(remote_ip, false); } if (!isCheck.Keys.Contains(remote_ip)) { isCheck.Add(remote_ip, false); } if (!saoMa.Keys.Contains(remote_ip)) { saoMa.Add(remote_ip, 3); } } //LogHelper.Info($"接收到信息,IP:{remote_ip},MSG:{BitConverter.ToString(buffers[remote_ip])}"); if (buffers.Keys.Contains(remote_ip)) { var messageBytes = new byte[length]; Array.Copy(buffers[remote_ip], 0, messageBytes, 0, length); try { //读卡器校验 var message = BitConverter.ToString(messageBytes); if (!saoMa.ContainsKey(remote_ip)) { saoMa.Add(remote_ip, 3); } if (messageBytes.Length <= 20 && messageBytes.Length > 0) { saoMa[remote_ip] = 3;//未扫到码 } if (messageBytes.Length >= 21 && isCheck[remote_ip]) { byte[] rfid = new byte[12]; Array.Copy(messageBytes, 9, rfid, 0, 12); string rfids16 = BitConverter.ToString(rfid); string rfids = Encoding.ASCII.GetString(rfid); LogHelper.Info($"读卡器校验对应容器号:{rfids},其16进制形式:{rfids16}"); if (ScanCodeHelper.Analysis(remote_ip, rfids))//校验RFID { isCheck[remote_ip] = true; saoMa[remote_ip] = 1;//扫码匹配 } else { isCheck[remote_ip] = true; saoMa[remote_ip] = 2;//扫码不匹配 } } else { LogHelper.Info($"不满足读卡器校验规定:IP:{remote_ip},MSG:{message}"); } } catch(Exception ex) { LogHelper.Info($"扫码校验发生了异常:{ex.Message}"); saoMa[remote_ip] = 4;//扫码异常 } try { //卷帘门开关 var plc = Settings.SafeDoorDevices.FirstOrDefault(a => a.IPAddress == remote_ip); var log = BitConverter.ToString(messageBytes); if (plc != null && messageBytes[0] == 0x3F && messageBytes[1] == 0x00 && messageBytes[2] == 0x11 && messageBytes[3] == 0x0d && messageBytes[4] == 0x0a && isSend[remote_ip]) { LogHelper.Info($"{plc.DeviceName}设备开门完成,{log}"); var dic = new List(); dic.Add(new param() { name = "From", value = "1" }); dic.Add(new param() { name = "To", value = plc.DeviceCode }); var resAgv = NDCApi.AddOrderNew(164, 1, System.DateTime.Now.Ticks.ToString(), dic); LogHelper.Info($"通知AGV通过安全门,返回结果:{JsonConvert.SerializeObject(resAgv)}设备开门完成"); if (resAgv.err_code == 0) { isSend[remote_ip] = false; } } else { LogHelper.Info($"{remote_ip}设备返回:{log}"); } } catch(Exception ex) { LogHelper.Info($"卷帘门校验发生了异常:{ex.Message}"); } //TcpServerSend(remote_ip, System.Text.Encoding.Default.GetBytes(msgSend)); Array.Clear(buffers[remote_ip], 0, buffers[remote_ip].Length);//清空当前IP Buffer } else { if (!buffers.Keys.Contains(remote_ip)) { buffers.Add(remote_ip, new byte[1024]); } } //接收下一个消息(因为这是一个递归的调用,所以这样就可以一直接收消息了) socket.BeginReceive(buffers[remote_ip], 0, buffers[remote_ip].Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket); } catch (Exception ex) { LogHelper.Error(ex.Message, ex); } } 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); LogHelper.Info($"已发送给该AGV地址{ip},{msg}"); return true; } catch (SocketException ex) { LogHelper.Info(ex.Message, "Error"); clients[ip].Close(); clients.Remove(ip); } } else { clients[ip].Close(); clients.Remove(ip); } } else { LogHelper.Info("未找到该设备,是否已连接?"); } return false; } } }