using IoTClient.Common.Constants; using IoTClient.Common.Helpers; using IoTServer.Common; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Threading.Tasks; namespace IoTServer.Servers.PLC { public class SiemensServer { private Socket socketServer; private string ip; private int port; List sockets = new List(); DataPersist dataPersist; public SiemensServer(int port, string ip = null) { this.ip = ip; this.port = port; dataPersist = new DataPersist("SiemensServer"); } /// /// 启动服务 /// public void Start() { //1 创建Socket对象 socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //2 绑定ip和端口 var ipaddress = string.IsNullOrWhiteSpace(ip) ? IPAddress.Any : IPAddress.Parse(ip); IPEndPoint ipEndPoint = new IPEndPoint(ipaddress, port); socketServer.Bind(ipEndPoint); //3、开启侦听(等待客户机发出的连接),并设置最大客户端连接数为10 socketServer.Listen(10); Task.Run(() => { Accept(socketServer); }); } /// /// 停止服务 /// public void Stop() { if (socketServer?.Connected ?? false) socketServer.Shutdown(SocketShutdown.Both); socketServer?.Close(); } /// /// 客户端连接到服务端 /// /// void Accept(Socket socket) { while (true) { try { Socket newSocket = null; try { //阻塞等待客户端连接 newSocket = socket.Accept(); sockets.Add(newSocket); Task.Run(() => { Receive(newSocket); }); } catch (SocketException) { foreach (var item in sockets) { if (item?.Connected ?? false) item.Shutdown(SocketShutdown.Both); item?.Close(); } } } catch (SocketException ex) { if (ex.SocketErrorCode != SocketError.Interrupted) throw ex; } } } /// /// 接收客户端发送的消息 /// /// void Receive(Socket newSocket) { while (newSocket.Connected) { try { byte[] requetData1 = new byte[4]; //读取客户端发送过来的数据 int readLeng = newSocket.Receive(requetData1, 0, requetData1.Length, SocketFlags.None); if (readLeng == 0)//客户端断开连接 { newSocket.Shutdown(SocketShutdown.Both); newSocket.Close(); return; } byte[] requetData2 = new byte[requetData1[3] - 4]; readLeng = newSocket.Receive(requetData2, 0, requetData2.Length, SocketFlags.None); if (readLeng == 0)//客户端断开连接 { if (newSocket?.Connected ?? false) newSocket.Shutdown(SocketShutdown.Both); newSocket?.Close(); return; } var requetData = requetData1.Concat(requetData2).ToArray(); //如果是连接的时候发送的两次初始化指令 则直接跳过 if (requetData[3] == SiemensConstant.Command1_200Smart.Length || requetData[3] == SiemensConstant.Command2_200Smart.Length) { newSocket.Send(requetData); continue; } var address = requetData[28] * 256 * 256 + requetData[29] * 256 + requetData[30]; switch (requetData[17]) { //读 case 4: { var value = dataPersist.Read(address);//TODO 数据存在 25、26 //把存储的数据转为字节数组 var bytes = JsonConvert.DeserializeObject(value); if (string.IsNullOrWhiteSpace(value)) bytes = BitConverter.GetBytes(0); var dataContent = new byte[4 + bytes.Length];//可以从报文中获取Length? DataConvert.StringToByteArray("FF 09 00 04").CopyTo(dataContent, 0); dataContent[1] = bytes.Length == 1 ? (byte)0x03 : (byte)0x04;//04 byte(字节) 03bit(位) dataContent[2] = (byte)(bytes.Length / 256); dataContent[3] = (byte)(bytes.Length % 256); //dataContent[0] 固定 //dataContent[2] dataContent[3] 后半截数据数组的Length //dataContent[4]-[7] 返回给客户端的数据 byte[] responseData1 = new byte[21 + dataContent.Length]; DataConvert.StringToByteArray("03 00 00 1A 02 F0 80 32 03 00 00 00 01 00 02 00 00 00 00 04 01").CopyTo(responseData1, 0); //responseData1[0] = 0x03; //responseData1[1] = 0x00; //固定协议头 //responseData1[8] = 0x03;//1 客户端发送命令 3 服务器回复命令 responseData1[2] = (byte)(responseData1.Length / 256); responseData1[3] = (byte)(responseData1.Length % 256); responseData1[15] = (byte)(requetData.Length / 256); responseData1[16] = (byte)(requetData.Length % 256); responseData1[20] = requetData[18]; dataContent.CopyTo(responseData1, 21); Buffer.BlockCopy(bytes, 0, responseData1, responseData1.Length - bytes.Length, bytes.Length); newSocket.Send(responseData1); } break; //写 case 5: { var valueByte = new byte[requetData.Length - 35]; Buffer.BlockCopy(requetData, 35, valueByte, 0, valueByte.Length); //存储字节数据到内存 dataPersist.Write(address, JsonConvert.SerializeObject(valueByte)); byte[] responseData1 = new byte[22]; DataConvert.StringToByteArray("03 00 00 16 02 F0 80 32 03 00 00 00 01 00 02 00 01 00 00 05 01 FF").CopyTo(responseData1, 0); //responseData1[15] = (byte)(responseData1.Length / 256); //responseData1[16] = (byte)(responseData1.Length % 256); newSocket.Send(responseData1); } break; } } catch (SocketException ex) { //todo //if (ex.SocketErrorCode != SocketError.ConnectionRefused && // ex.SocketErrorCode != SocketError.ConnectionReset) // throw ex; } } } } }