From 7e072b51ac8b0bed148cf17596df455b03ea994e Mon Sep 17 00:00:00 2001 From: BennyZhao Date: Tue, 23 Jun 2020 16:36:03 +0800 Subject: [PATCH] =?UTF-8?q?SiemensClient=20=E4=BB=8E=E5=8F=91=E9=80=81?= =?UTF-8?q?=E5=91=BD=E4=BB=A4=E5=88=B0=E8=AF=BB=E5=8F=96=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E4=B8=BA=E6=9C=80=E5=B0=8F=E5=8D=95=E5=85=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IoTClient.Tool/IndexForm.Designer.cs | 32 +++++++------- IoTClient.Tool/Model/VersionCheckInput.cs | 2 +- IoTClient/Clients/PLC/SiemensClient.cs | 52 +++++++++++++++++++---- IoTServer/Common/DataPersist.cs | 15 ++++--- IoTServer/IoTServer.csproj | 5 +-- IoTServer/Servers/PLC/SiemensServer.cs | 2 +- README.md | 34 +++++++++++++++ 7 files changed, 105 insertions(+), 37 deletions(-) diff --git a/IoTClient.Tool/IndexForm.Designer.cs b/IoTClient.Tool/IndexForm.Designer.cs index 82c5fec..9eda57b 100644 --- a/IoTClient.Tool/IndexForm.Designer.cs +++ b/IoTClient.Tool/IndexForm.Designer.cs @@ -31,6 +31,7 @@ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(IndexForm)); this.tabControl1 = new System.Windows.Forms.TabControl(); this.ModBusTcp = new System.Windows.Forms.TabPage(); + this.modBusTcpControl1 = new IoTClient.Tool.ModBusTcpControl(); this.ModBusRtu = new System.Windows.Forms.TabPage(); this.ModBusAscii = new System.Windows.Forms.TabPage(); this.Siemens = new System.Windows.Forms.TabPage(); @@ -46,9 +47,8 @@ this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItemBlogPath = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); this.商务合作ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.modBusTcpControl1 = new IoTClient.Tool.ModBusTcpControl(); + this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); this.tabControl1.SuspendLayout(); this.ModBusTcp.SuspendLayout(); this.menuStrip1.SuspendLayout(); @@ -85,6 +85,14 @@ this.ModBusTcp.Text = "ModBusTcp"; this.ModBusTcp.UseVisualStyleBackColor = true; // + // modBusTcpControl1 + // + this.modBusTcpControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.modBusTcpControl1.Location = new System.Drawing.Point(3, 3); + this.modBusTcpControl1.Name = "modBusTcpControl1"; + this.modBusTcpControl1.Size = new System.Drawing.Size(880, 442); + this.modBusTcpControl1.TabIndex = 0; + // // ModBusRtu // this.ModBusRtu.Location = new System.Drawing.Point(4, 22); @@ -232,14 +240,6 @@ this.toolStripMenuItem4.Text = "交流群"; this.toolStripMenuItem4.Click += new System.EventHandler(this.toolStripMenuItem4_Click); // - // toolStripMenuItem1 - // - this.toolStripMenuItem1.ForeColor = System.Drawing.Color.White; - this.toolStripMenuItem1.Name = "toolStripMenuItem1"; - this.toolStripMenuItem1.Size = new System.Drawing.Size(75, 21); - this.toolStripMenuItem1.Text = "版本 0.3.5"; - this.toolStripMenuItem1.Click += new System.EventHandler(this.toolStripMenuItem1_Click); - // // 商务合作ToolStripMenuItem // this.商务合作ToolStripMenuItem.ForeColor = System.Drawing.Color.White; @@ -248,13 +248,13 @@ this.商务合作ToolStripMenuItem.Text = "商务合作"; this.商务合作ToolStripMenuItem.Click += new System.EventHandler(this.cooperationToolStripMenuItem_Click); // - // modBusTcpControl1 + // toolStripMenuItem1 // - this.modBusTcpControl1.Dock = System.Windows.Forms.DockStyle.Fill; - this.modBusTcpControl1.Location = new System.Drawing.Point(3, 3); - this.modBusTcpControl1.Name = "modBusTcpControl1"; - this.modBusTcpControl1.Size = new System.Drawing.Size(880, 442); - this.modBusTcpControl1.TabIndex = 0; + this.toolStripMenuItem1.ForeColor = System.Drawing.Color.White; + this.toolStripMenuItem1.Name = "toolStripMenuItem1"; + this.toolStripMenuItem1.Size = new System.Drawing.Size(75, 21); + this.toolStripMenuItem1.Text = "版本 0.3.6"; + this.toolStripMenuItem1.Click += new System.EventHandler(this.toolStripMenuItem1_Click); // // IndexForm // diff --git a/IoTClient.Tool/Model/VersionCheckInput.cs b/IoTClient.Tool/Model/VersionCheckInput.cs index 122ad3e..a4d925a 100644 --- a/IoTClient.Tool/Model/VersionCheckInput.cs +++ b/IoTClient.Tool/Model/VersionCheckInput.cs @@ -5,7 +5,7 @@ /// /// 当前版本 /// - public float CurrentVersion { get; set; } = 0.35f; + public float CurrentVersion { get; set; } = 0.36f; /// /// 忽略版本 diff --git a/IoTClient/Clients/PLC/SiemensClient.cs b/IoTClient/Clients/PLC/SiemensClient.cs index 0ac577c..cefe8c3 100644 --- a/IoTClient/Clients/PLC/SiemensClient.cs +++ b/IoTClient/Clients/PLC/SiemensClient.cs @@ -99,10 +99,14 @@ namespace IoTClient.Clients.PLC /// public byte[] SendPackage(byte[] command) { - socket.Send(command); - var headPackage = SocketRead(socket, SiemensConstant.InitHeadLength); - var dataPackage = SocketRead(socket, GetContentLength(headPackage)); - return headPackage.Concat(dataPackage).ToArray(); + //从发送命令到读取响应为最小单元,避免多线程执行串数据(可线程安全执行) + lock (this) + { + socket.Send(command); + var headPackage = SocketRead(socket, SiemensConstant.InitHeadLength); + var dataPackage = SocketRead(socket, GetContentLength(headPackage)); + return headPackage.Concat(dataPackage).ToArray(); + } } #endregion @@ -121,7 +125,7 @@ namespace IoTClient.Clients.PLC try { //兼容地址,如VD5012中的D - if (address.Length >= 2 && !"0123456789".Contains(address[1].ToString())) address = address.Remove(1, 1); + //if (address.Length >= 2 && !"0123456789".Contains(address[1].ToString())) address = address.Remove(1, 1); //发送读取信息 var arg = ConvertArg(address); byte[] command; @@ -153,6 +157,14 @@ namespace IoTClient.Clients.PLC socket?.Shutdown(SocketShutdown.Both); socket?.Close(); } + catch (Exception ex) + { + result.IsSucceed = false; + result.Err = ex.Message; + result.ErrList.Add(ex.Message); + socket?.Shutdown(SocketShutdown.Both); + socket?.Close(); + } finally { if (isAutoOpen) Dispose(); @@ -173,7 +185,7 @@ namespace IoTClient.Clients.PLC try { //兼容地址,如VD5012中的D - if (address.Length >= 2 && !"0123456789".Contains(address[1].ToString())) address = address.Remove(1, 1); + //if (address.Length >= 2 && !"0123456789".Contains(address[1].ToString())) address = address.Remove(1, 1); //发送读取信息 var arg = ConvertArg(address); byte[] command = GetReadCommand(arg.TypeCode, arg.BeginAddress, arg.DbBlock, length); @@ -201,6 +213,14 @@ namespace IoTClient.Clients.PLC socket?.Shutdown(SocketShutdown.Both); socket?.Close(); } + catch (Exception ex) + { + result.IsSucceed = false; + result.Err = ex.Message; + result.ErrList.Add(ex.Message); + socket?.Shutdown(SocketShutdown.Both); + socket?.Close(); + } finally { if (isAutoOpen) Dispose(); @@ -782,7 +802,7 @@ namespace IoTClient.Clients.PLC try { //兼容地址,如VD5012中的D - if (address.Length >= 2 && !"0123456789".Contains(address[1].ToString())) address = address.Remove(1, 1); + //if (address.Length >= 2 && !"0123456789".Contains(address[1].ToString())) address = address.Remove(1, 1); //发送写入信息 var arg = ConvertArg(address); byte[] command = GetWriteByteCommand(arg.TypeCode, arg.BeginAddress, arg.DbBlock, value); @@ -806,6 +826,14 @@ namespace IoTClient.Clients.PLC socket?.Shutdown(SocketShutdown.Both); socket?.Close(); } + catch (Exception ex) + { + result.IsSucceed = false; + result.Err = ex.Message; + result.ErrList.Add(ex.Message); + socket?.Shutdown(SocketShutdown.Both); + socket?.Close(); + } finally { if (isAutoOpen) Dispose(); @@ -827,7 +855,7 @@ namespace IoTClient.Clients.PLC { Array.Reverse(data); //兼容地址,如VD5012中的D - if (address.Length >= 2 && !"0123456789".Contains(address[1].ToString())) address = address.Remove(1, 1); + //if (address.Length >= 2 && !"0123456789".Contains(address[1].ToString())) address = address.Remove(1, 1); //发送写入信息 var arg = ConvertArg(address); byte[] command = GetWriteCommand(arg.TypeCode, arg.BeginAddress, arg.DbBlock, data); @@ -851,6 +879,14 @@ namespace IoTClient.Clients.PLC socket?.Shutdown(SocketShutdown.Both); socket?.Close(); } + catch (Exception ex) + { + result.IsSucceed = false; + result.Err = ex.Message; + result.ErrList.Add(ex.Message); + socket?.Shutdown(SocketShutdown.Both); + socket?.Close(); + } finally { if (isAutoOpen) Dispose(); diff --git a/IoTServer/Common/DataPersist.cs b/IoTServer/Common/DataPersist.cs index b31fe54..e6abf28 100644 --- a/IoTServer/Common/DataPersist.cs +++ b/IoTServer/Common/DataPersist.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; @@ -8,7 +9,7 @@ namespace IoTServer.Common public class DataPersist { string prefix; - static Dictionary data = new Dictionary(); + static ConcurrentDictionary data = new ConcurrentDictionary(); /// /// @@ -27,7 +28,7 @@ namespace IoTServer.Common public string Read(string key) { key = prefix + key; - if (data.Keys.Contains(key)) + if (data.ContainsKey(key)) { return data[key]; } @@ -46,14 +47,14 @@ namespace IoTServer.Common /// public void Write(string key, string value) { - key = prefix + key; - if (data.Keys.Contains(key)) + key = prefix + key; + if (data.ContainsKey(key)) { data[key] = value; } else { - data.Add(key, value); + data.TryAdd(key, value); } } @@ -67,7 +68,7 @@ namespace IoTServer.Common /// public static void Clear() { - data = new Dictionary(); + data = new ConcurrentDictionary(); } /// @@ -104,7 +105,7 @@ namespace IoTServer.Common File.SetAttributes(path, FileAttributes.Hidden); } if (!string.IsNullOrWhiteSpace(dataString)) - data = JsonConvert.DeserializeObject>(dataString); + data = JsonConvert.DeserializeObject>(dataString); } } } diff --git a/IoTServer/IoTServer.csproj b/IoTServer/IoTServer.csproj index 4d833c0..058f331 100644 --- a/IoTServer/IoTServer.csproj +++ b/IoTServer/IoTServer.csproj @@ -30,11 +30,8 @@ + - - - - diff --git a/IoTServer/Servers/PLC/SiemensServer.cs b/IoTServer/Servers/PLC/SiemensServer.cs index f5cb7ac..e84b8fc 100644 --- a/IoTServer/Servers/PLC/SiemensServer.cs +++ b/IoTServer/Servers/PLC/SiemensServer.cs @@ -42,7 +42,7 @@ namespace IoTServer.Servers.PLC socketServer.Bind(ipEndPoint); //3、开启侦听(等待客户机发出的连接),并设置最大客户端连接数为10 - socketServer.Listen(10); + socketServer.Listen(100); Task.Run(() => { Accept(socketServer); }); } diff --git a/README.md b/README.md index 5a3a0c7..ecb79b2 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,40 @@ ModBusRtuClient client = new ModBusRtuClient("COM3", 9600, 8, StopBits.One, Pari //其他读写操作和ModBusTcpClient的读写操作一致 ``` +## SiemensClient读写操作 +``` +//1、实例化客户端 - 输入正确的IP和端口 +SiemensClient client = new SiemensClient(SiemensVersion.S7_200Smart, "127.0.0.1",102); + +//2、写操作 +client.Write("Q1.3", true); +client.Write("V2205", (short)11); +client.Write("V2209", 33); + +//3、读操作 +var value1 = client.ReadBoolean("Q1.3").Value; +var value2 = client.ReadInt16("V2205").Value; +var value3 = client.ReadInt32("V2209").Value; + +//4、如果没有主动Open,则会每次读写操作的时候自动打开自动和关闭连接,这样会使读写效率大大减低。所以建议手动Open和Close。 +client.Open(); + +//5、读写操作都会返回操作结果对象Result +var result = client.ReadInt16("V2205"); +//5.1 读取是否成功(true或false) +var isSucceed = result.IsSucceed; +//5.2 读取失败的异常信息 +var errMsg = result.Err; +//5.3 读取操作实际发送的请求报文 +var requst = result.Requst; +//5.4 读取操作服务端响应的报文 +var response = result.Response; +//5.5 读取到的值 +var value4 = result.Value; +``` + +## 其他更多详细使用请[参考](https://github.com/zhaopeiym/IoTClient/tree/master/IoTClient.Tool/Controls) + # IoTClient Tool效果图 ![image](https://user-images.githubusercontent.com/5820324/68926947-9c43e800-07c1-11ea-9da7-f431ec52f2fb.png)