mirror of
https://github.com/zhaopeiym/IoTClient
synced 2025-10-12 21:20:37 +08:00
新增ModBusRtu服务的仿真模拟
This commit is contained in:
parent
96542221ec
commit
f5a0df8e58
|
@ -1,5 +1,4 @@
|
|||
using IoTClient.Clients.ModBus;
|
||||
using IoTServer.Common;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
|
116
IoTClient.Tool/Controls/ModBusRtuControl.Designer.cs
generated
116
IoTClient.Tool/Controls/ModBusRtuControl.Designer.cs
generated
|
@ -40,6 +40,7 @@
|
|||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.button6 = new System.Windows.Forms.Button();
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
this.rd_discrete = new System.Windows.Forms.RadioButton();
|
||||
this.rd_float = new System.Windows.Forms.RadioButton();
|
||||
this.rd_double = new System.Windows.Forms.RadioButton();
|
||||
this.rd_short = new System.Windows.Forms.RadioButton();
|
||||
|
@ -58,13 +59,15 @@
|
|||
this.txt_dataBit = new System.Windows.Forms.TextBox();
|
||||
this.cb_portNameSend = new System.Windows.Forms.ComboBox();
|
||||
this.but_close = new System.Windows.Forms.Button();
|
||||
this.button2 = new System.Windows.Forms.Button();
|
||||
this.button1 = new System.Windows.Forms.Button();
|
||||
this.but_server_close = new System.Windows.Forms.Button();
|
||||
this.but_server_open = new System.Windows.Forms.Button();
|
||||
this.but_open = new System.Windows.Forms.Button();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.txt_stationNumber = new System.Windows.Forms.TextBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.cb_portNameSend_server = new System.Windows.Forms.ComboBox();
|
||||
this.label8 = new System.Windows.Forms.Label();
|
||||
this.groupBox3.SuspendLayout();
|
||||
this.groupBox1.SuspendLayout();
|
||||
this.groupBox2.SuspendLayout();
|
||||
|
@ -104,7 +107,7 @@
|
|||
this.but_write.TabIndex = 10;
|
||||
this.but_write.Text = "写入";
|
||||
this.but_write.UseVisualStyleBackColor = true;
|
||||
this.but_write.Click += new System.EventHandler(this.butWrite_Click);
|
||||
this.but_write.Click += new System.EventHandler(this.but_write_Click);
|
||||
//
|
||||
// txt_value
|
||||
//
|
||||
|
@ -158,6 +161,7 @@
|
|||
//
|
||||
// groupBox1
|
||||
//
|
||||
this.groupBox1.Controls.Add(this.rd_discrete);
|
||||
this.groupBox1.Controls.Add(this.button6);
|
||||
this.groupBox1.Controls.Add(this.rd_float);
|
||||
this.groupBox1.Controls.Add(this.rd_double);
|
||||
|
@ -174,10 +178,20 @@
|
|||
this.groupBox1.TabIndex = 32;
|
||||
this.groupBox1.TabStop = false;
|
||||
//
|
||||
// rd_discrete
|
||||
//
|
||||
this.rd_discrete.AutoSize = true;
|
||||
this.rd_discrete.Location = new System.Drawing.Point(64, 23);
|
||||
this.rd_discrete.Name = "rd_discrete";
|
||||
this.rd_discrete.Size = new System.Drawing.Size(47, 16);
|
||||
this.rd_discrete.TabIndex = 24;
|
||||
this.rd_discrete.Text = "离散";
|
||||
this.rd_discrete.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// rd_float
|
||||
//
|
||||
this.rd_float.AutoSize = true;
|
||||
this.rd_float.Location = new System.Drawing.Point(436, 23);
|
||||
this.rd_float.Location = new System.Drawing.Point(486, 23);
|
||||
this.rd_float.Name = "rd_float";
|
||||
this.rd_float.Size = new System.Drawing.Size(53, 16);
|
||||
this.rd_float.TabIndex = 22;
|
||||
|
@ -187,7 +201,7 @@
|
|||
// rd_double
|
||||
//
|
||||
this.rd_double.AutoSize = true;
|
||||
this.rd_double.Location = new System.Drawing.Point(495, 23);
|
||||
this.rd_double.Location = new System.Drawing.Point(545, 23);
|
||||
this.rd_double.Name = "rd_double";
|
||||
this.rd_double.Size = new System.Drawing.Size(59, 16);
|
||||
this.rd_double.TabIndex = 23;
|
||||
|
@ -198,7 +212,7 @@
|
|||
//
|
||||
this.rd_short.AutoSize = true;
|
||||
this.rd_short.Checked = true;
|
||||
this.rd_short.Location = new System.Drawing.Point(70, 23);
|
||||
this.rd_short.Location = new System.Drawing.Point(120, 23);
|
||||
this.rd_short.Name = "rd_short";
|
||||
this.rd_short.Size = new System.Drawing.Size(53, 16);
|
||||
this.rd_short.TabIndex = 6;
|
||||
|
@ -219,7 +233,7 @@
|
|||
// rd_ulong
|
||||
//
|
||||
this.rd_ulong.AutoSize = true;
|
||||
this.rd_ulong.Location = new System.Drawing.Point(374, 23);
|
||||
this.rd_ulong.Location = new System.Drawing.Point(424, 23);
|
||||
this.rd_ulong.Name = "rd_ulong";
|
||||
this.rd_ulong.Size = new System.Drawing.Size(53, 16);
|
||||
this.rd_ulong.TabIndex = 21;
|
||||
|
@ -229,7 +243,7 @@
|
|||
// rd_ushort
|
||||
//
|
||||
this.rd_ushort.AutoSize = true;
|
||||
this.rd_ushort.Location = new System.Drawing.Point(129, 23);
|
||||
this.rd_ushort.Location = new System.Drawing.Point(179, 23);
|
||||
this.rd_ushort.Name = "rd_ushort";
|
||||
this.rd_ushort.Size = new System.Drawing.Size(59, 16);
|
||||
this.rd_ushort.TabIndex = 17;
|
||||
|
@ -239,7 +253,7 @@
|
|||
// rd_long
|
||||
//
|
||||
this.rd_long.AutoSize = true;
|
||||
this.rd_long.Location = new System.Drawing.Point(315, 23);
|
||||
this.rd_long.Location = new System.Drawing.Point(365, 23);
|
||||
this.rd_long.Name = "rd_long";
|
||||
this.rd_long.Size = new System.Drawing.Size(47, 16);
|
||||
this.rd_long.TabIndex = 20;
|
||||
|
@ -249,7 +263,7 @@
|
|||
// rd_int
|
||||
//
|
||||
this.rd_int.AutoSize = true;
|
||||
this.rd_int.Location = new System.Drawing.Point(194, 23);
|
||||
this.rd_int.Location = new System.Drawing.Point(244, 23);
|
||||
this.rd_int.Name = "rd_int";
|
||||
this.rd_int.Size = new System.Drawing.Size(41, 16);
|
||||
this.rd_int.TabIndex = 18;
|
||||
|
@ -259,7 +273,7 @@
|
|||
// rd_uint
|
||||
//
|
||||
this.rd_uint.AutoSize = true;
|
||||
this.rd_uint.Location = new System.Drawing.Point(253, 23);
|
||||
this.rd_uint.Location = new System.Drawing.Point(303, 23);
|
||||
this.rd_uint.Name = "rd_uint";
|
||||
this.rd_uint.Size = new System.Drawing.Size(47, 16);
|
||||
this.rd_uint.TabIndex = 19;
|
||||
|
@ -268,7 +282,7 @@
|
|||
//
|
||||
// txt_baudRate
|
||||
//
|
||||
this.txt_baudRate.Location = new System.Drawing.Point(131, 19);
|
||||
this.txt_baudRate.Location = new System.Drawing.Point(127, 19);
|
||||
this.txt_baudRate.Name = "txt_baudRate";
|
||||
this.txt_baudRate.Size = new System.Drawing.Size(42, 21);
|
||||
this.txt_baudRate.TabIndex = 5;
|
||||
|
@ -286,14 +300,16 @@
|
|||
//
|
||||
// groupBox2
|
||||
//
|
||||
this.groupBox2.Controls.Add(this.cb_portNameSend_server);
|
||||
this.groupBox2.Controls.Add(this.label8);
|
||||
this.groupBox2.Controls.Add(this.label7);
|
||||
this.groupBox2.Controls.Add(this.txt_stopBit);
|
||||
this.groupBox2.Controls.Add(this.label6);
|
||||
this.groupBox2.Controls.Add(this.txt_dataBit);
|
||||
this.groupBox2.Controls.Add(this.cb_portNameSend);
|
||||
this.groupBox2.Controls.Add(this.but_close);
|
||||
this.groupBox2.Controls.Add(this.button2);
|
||||
this.groupBox2.Controls.Add(this.button1);
|
||||
this.groupBox2.Controls.Add(this.but_server_close);
|
||||
this.groupBox2.Controls.Add(this.but_server_open);
|
||||
this.groupBox2.Controls.Add(this.but_open);
|
||||
this.groupBox2.Controls.Add(this.label5);
|
||||
this.groupBox2.Controls.Add(this.txt_stationNumber);
|
||||
|
@ -309,7 +325,7 @@
|
|||
// label7
|
||||
//
|
||||
this.label7.AutoSize = true;
|
||||
this.label7.Location = new System.Drawing.Point(253, 23);
|
||||
this.label7.Location = new System.Drawing.Point(250, 23);
|
||||
this.label7.Name = "label7";
|
||||
this.label7.Size = new System.Drawing.Size(41, 12);
|
||||
this.label7.TabIndex = 21;
|
||||
|
@ -317,7 +333,7 @@
|
|||
//
|
||||
// txt_stopBit
|
||||
//
|
||||
this.txt_stopBit.Location = new System.Drawing.Point(296, 19);
|
||||
this.txt_stopBit.Location = new System.Drawing.Point(292, 19);
|
||||
this.txt_stopBit.Name = "txt_stopBit";
|
||||
this.txt_stopBit.Size = new System.Drawing.Size(24, 21);
|
||||
this.txt_stopBit.TabIndex = 22;
|
||||
|
@ -326,7 +342,7 @@
|
|||
// label6
|
||||
//
|
||||
this.label6.AutoSize = true;
|
||||
this.label6.Location = new System.Drawing.Point(178, 24);
|
||||
this.label6.Location = new System.Drawing.Point(176, 24);
|
||||
this.label6.Name = "label6";
|
||||
this.label6.Size = new System.Drawing.Size(41, 12);
|
||||
this.label6.TabIndex = 19;
|
||||
|
@ -334,7 +350,7 @@
|
|||
//
|
||||
// txt_dataBit
|
||||
//
|
||||
this.txt_dataBit.Location = new System.Drawing.Point(219, 20);
|
||||
this.txt_dataBit.Location = new System.Drawing.Point(217, 20);
|
||||
this.txt_dataBit.Name = "txt_dataBit";
|
||||
this.txt_dataBit.Size = new System.Drawing.Size(24, 21);
|
||||
this.txt_dataBit.TabIndex = 20;
|
||||
|
@ -343,14 +359,14 @@
|
|||
// cb_portNameSend
|
||||
//
|
||||
this.cb_portNameSend.FormattingEnabled = true;
|
||||
this.cb_portNameSend.Location = new System.Drawing.Point(35, 20);
|
||||
this.cb_portNameSend.Location = new System.Drawing.Point(34, 20);
|
||||
this.cb_portNameSend.Name = "cb_portNameSend";
|
||||
this.cb_portNameSend.Size = new System.Drawing.Size(47, 20);
|
||||
this.cb_portNameSend.TabIndex = 18;
|
||||
//
|
||||
// but_close
|
||||
//
|
||||
this.but_close.Location = new System.Drawing.Point(419, 19);
|
||||
this.but_close.Location = new System.Drawing.Point(466, 19);
|
||||
this.but_close.Name = "but_close";
|
||||
this.but_close.Size = new System.Drawing.Size(75, 23);
|
||||
this.but_close.TabIndex = 17;
|
||||
|
@ -360,25 +376,27 @@
|
|||
//
|
||||
// button2
|
||||
//
|
||||
this.button2.Location = new System.Drawing.Point(768, 19);
|
||||
this.button2.Name = "button2";
|
||||
this.button2.Size = new System.Drawing.Size(75, 23);
|
||||
this.button2.TabIndex = 16;
|
||||
this.button2.Text = "关闭服务";
|
||||
this.button2.UseVisualStyleBackColor = true;
|
||||
this.but_server_close.Location = new System.Drawing.Point(768, 19);
|
||||
this.but_server_close.Name = "button2";
|
||||
this.but_server_close.Size = new System.Drawing.Size(75, 23);
|
||||
this.but_server_close.TabIndex = 16;
|
||||
this.but_server_close.Text = "关闭服务";
|
||||
this.but_server_close.UseVisualStyleBackColor = true;
|
||||
this.but_server_close.Click += new System.EventHandler(this.but_close_server_Click);
|
||||
//
|
||||
// button1
|
||||
//
|
||||
this.button1.Location = new System.Drawing.Point(663, 19);
|
||||
this.button1.Name = "button1";
|
||||
this.button1.Size = new System.Drawing.Size(99, 23);
|
||||
this.button1.TabIndex = 0;
|
||||
this.button1.Text = "本地模拟服务";
|
||||
this.button1.UseVisualStyleBackColor = true;
|
||||
this.but_server_open.Location = new System.Drawing.Point(665, 19);
|
||||
this.but_server_open.Name = "button1";
|
||||
this.but_server_open.Size = new System.Drawing.Size(99, 23);
|
||||
this.but_server_open.TabIndex = 0;
|
||||
this.but_server_open.Text = "本地模拟服务";
|
||||
this.but_server_open.UseVisualStyleBackColor = true;
|
||||
this.but_server_open.Click += new System.EventHandler(this.but_open_server_Click);
|
||||
//
|
||||
// but_open
|
||||
//
|
||||
this.but_open.Location = new System.Drawing.Point(338, 18);
|
||||
this.but_open.Location = new System.Drawing.Point(385, 18);
|
||||
this.but_open.Name = "but_open";
|
||||
this.but_open.Size = new System.Drawing.Size(75, 23);
|
||||
this.but_open.TabIndex = 1;
|
||||
|
@ -389,7 +407,7 @@
|
|||
// label5
|
||||
//
|
||||
this.label5.AutoSize = true;
|
||||
this.label5.Location = new System.Drawing.Point(528, 23);
|
||||
this.label5.Location = new System.Drawing.Point(324, 23);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(29, 12);
|
||||
this.label5.TabIndex = 15;
|
||||
|
@ -397,9 +415,9 @@
|
|||
//
|
||||
// txt_stationNumber
|
||||
//
|
||||
this.txt_stationNumber.Location = new System.Drawing.Point(563, 19);
|
||||
this.txt_stationNumber.Location = new System.Drawing.Point(353, 19);
|
||||
this.txt_stationNumber.Name = "txt_stationNumber";
|
||||
this.txt_stationNumber.Size = new System.Drawing.Size(35, 21);
|
||||
this.txt_stationNumber.Size = new System.Drawing.Size(25, 21);
|
||||
this.txt_stationNumber.TabIndex = 14;
|
||||
this.txt_stationNumber.Text = "1";
|
||||
//
|
||||
|
@ -415,12 +433,29 @@
|
|||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(90, 24);
|
||||
this.label2.Location = new System.Drawing.Point(86, 24);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(41, 12);
|
||||
this.label2.TabIndex = 4;
|
||||
this.label2.Text = "波特率";
|
||||
//
|
||||
// cb_portNameSend_server
|
||||
//
|
||||
this.cb_portNameSend_server.FormattingEnabled = true;
|
||||
this.cb_portNameSend_server.Location = new System.Drawing.Point(614, 21);
|
||||
this.cb_portNameSend_server.Name = "cb_portNameSend_server";
|
||||
this.cb_portNameSend_server.Size = new System.Drawing.Size(47, 20);
|
||||
this.cb_portNameSend_server.TabIndex = 24;
|
||||
//
|
||||
// label8
|
||||
//
|
||||
this.label8.AutoSize = true;
|
||||
this.label8.Location = new System.Drawing.Point(587, 25);
|
||||
this.label8.Name = "label8";
|
||||
this.label8.Size = new System.Drawing.Size(29, 12);
|
||||
this.label8.TabIndex = 23;
|
||||
this.label8.Text = "端口";
|
||||
//
|
||||
// ModBusRtuControl
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
|
||||
|
@ -468,8 +503,8 @@
|
|||
private System.Windows.Forms.TextBox txt_content;
|
||||
private System.Windows.Forms.GroupBox groupBox2;
|
||||
private System.Windows.Forms.Button but_close;
|
||||
private System.Windows.Forms.Button button2;
|
||||
private System.Windows.Forms.Button button1;
|
||||
private System.Windows.Forms.Button but_server_close;
|
||||
private System.Windows.Forms.Button but_server_open;
|
||||
private System.Windows.Forms.Button but_open;
|
||||
private System.Windows.Forms.Label label5;
|
||||
private System.Windows.Forms.TextBox txt_stationNumber;
|
||||
|
@ -480,5 +515,8 @@
|
|||
private System.Windows.Forms.TextBox txt_stopBit;
|
||||
private System.Windows.Forms.Label label6;
|
||||
private System.Windows.Forms.TextBox txt_dataBit;
|
||||
private System.Windows.Forms.RadioButton rd_discrete;
|
||||
private System.Windows.Forms.ComboBox cb_portNameSend_server;
|
||||
private System.Windows.Forms.Label label8;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
using IoTClient.Clients.ModBus;
|
||||
using IoTServer.Servers.ModBus;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.IO.Ports;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace IoTClient.Tool.Controls
|
||||
{
|
||||
public partial class ModBusRtuControl : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// 串行端口对象
|
||||
/// </summary>
|
||||
//private SerialPort serialPort;
|
||||
private ModBusRtuClient modBusRtuClient;
|
||||
|
||||
private ModBusRtuClient client;
|
||||
private ModBusRtuServer server;
|
||||
public ModBusRtuControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
@ -29,10 +25,11 @@ namespace IoTClient.Tool.Controls
|
|||
txt_content.Location = new Point(13, 160);
|
||||
but_read.Enabled = false;
|
||||
but_write.Enabled = false;
|
||||
button2.Enabled = false;
|
||||
but_server_close.Enabled = false;
|
||||
but_close.Enabled = false;
|
||||
UpdatePortNames();
|
||||
cb_portNameSend.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||
cb_portNameSend_server.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -40,9 +37,15 @@ namespace IoTClient.Tool.Controls
|
|||
/// </summary>
|
||||
public void UpdatePortNames()
|
||||
{
|
||||
cb_portNameSend.DataSource = SerialPort.GetPortNames();
|
||||
cb_portNameSend.DataSource = ModBusRtuClient.GetPortNames();
|
||||
cb_portNameSend_server.DataSource = ModBusRtuClient.GetPortNames();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 打开连接
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void but_open_Click(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
|
@ -51,9 +54,9 @@ namespace IoTClient.Tool.Controls
|
|||
var BaudRate = int.Parse(txt_baudRate.Text.ToString());
|
||||
var DataBits = int.Parse(txt_dataBit.Text.ToString());
|
||||
var StopBits = (StopBits)int.Parse(txt_stopBit.Text.ToString());
|
||||
|
||||
if (modBusRtuClient == null) modBusRtuClient = new ModBusRtuClient(PortName, BaudRate, DataBits, StopBits);
|
||||
var result = modBusRtuClient.Open();
|
||||
client?.Close();
|
||||
client = new ModBusRtuClient(PortName, BaudRate, DataBits, StopBits);
|
||||
var result = client.Open();
|
||||
if (result.IsSucceed)
|
||||
{
|
||||
but_open.Enabled = false;
|
||||
|
@ -66,7 +69,6 @@ namespace IoTClient.Tool.Controls
|
|||
}
|
||||
else
|
||||
AppendText($"连接失败:{result.Err}");
|
||||
UpdatePortNames();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -74,22 +76,101 @@ namespace IoTClient.Tool.Controls
|
|||
}
|
||||
}
|
||||
|
||||
private void AppendText(string content)
|
||||
{
|
||||
txt_content.Invoke((Action)(() =>
|
||||
{
|
||||
txt_content.AppendText($"[{DateTime.Now.ToLongTimeString()}]{content}\r\n");
|
||||
}));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送数据
|
||||
/// 关闭连接
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void butWrite_Click(object sender, EventArgs e)
|
||||
private void butClose_Click(object sender, EventArgs e)
|
||||
{
|
||||
var address = txt_address.Text?.Trim();
|
||||
client?.Close();
|
||||
AppendText("关闭连接");
|
||||
but_open.Enabled = true;
|
||||
but_close.Enabled = false;
|
||||
cb_portNameSend.Enabled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读数据
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void but_read_Click(object sender, EventArgs e)
|
||||
{
|
||||
byte.TryParse(txt_stationNumber.Text?.Trim(), out byte stationNumber);
|
||||
if (string.IsNullOrWhiteSpace(txt_address.Text))
|
||||
{
|
||||
MessageBox.Show("请输入地址");
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
dynamic result = null;
|
||||
if (rd_bit.Checked)
|
||||
{
|
||||
result = client.ReadCoil(txt_address.Text, stationNumber);
|
||||
}
|
||||
else if (rd_short.Checked)
|
||||
{
|
||||
result = client.ReadInt16(txt_address.Text, stationNumber);
|
||||
}
|
||||
else if (rd_ushort.Checked)
|
||||
{
|
||||
result = client.ReadUInt16(txt_address.Text, stationNumber);
|
||||
}
|
||||
else if (rd_int.Checked)
|
||||
{
|
||||
result = client.ReadInt32(txt_address.Text, stationNumber);
|
||||
}
|
||||
else if (rd_uint.Checked)
|
||||
{
|
||||
result = client.ReadUInt32(txt_address.Text, stationNumber);
|
||||
}
|
||||
else if (rd_long.Checked)
|
||||
{
|
||||
result = client.ReadInt64(txt_address.Text, stationNumber);
|
||||
}
|
||||
else if (rd_ulong.Checked)
|
||||
{
|
||||
result = client.ReadUInt64(txt_address.Text, stationNumber);
|
||||
}
|
||||
else if (rd_float.Checked)
|
||||
{
|
||||
result = client.ReadFloat(txt_address.Text, stationNumber);
|
||||
}
|
||||
else if (rd_double.Checked)
|
||||
{
|
||||
result = client.ReadDouble(txt_address.Text, stationNumber);
|
||||
}
|
||||
else if (rd_discrete.Checked)
|
||||
{
|
||||
result = client.ReadDiscrete(txt_address.Text, stationNumber);
|
||||
}
|
||||
|
||||
if (result.IsSucceed)
|
||||
txt_content.AppendText($"[{DateTime.Now.ToLongTimeString()}][读取 {txt_address.Text?.Trim()} 成功]:{result.Value}\r\n");
|
||||
else
|
||||
txt_content.AppendText($"[{DateTime.Now.ToLongTimeString()}][读取 {txt_address.Text?.Trim()} 失败]:{result.Err}\r\n");
|
||||
if (checkBox1.Checked)
|
||||
{
|
||||
txt_content.AppendText($"[请求报文]{result.Requst}\r\n");
|
||||
txt_content.AppendText($"[响应报文]{result.Response}\r\n\r\n");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写数据
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void but_write_Click(object sender, EventArgs e)
|
||||
{
|
||||
var address = txt_address.Text?.Trim();
|
||||
byte.TryParse(txt_stationNumber.Text?.Trim(), out byte stationNumber);
|
||||
if (string.IsNullOrWhiteSpace(txt_address.Text))
|
||||
{
|
||||
|
@ -119,40 +200,45 @@ namespace IoTClient.Tool.Controls
|
|||
return;
|
||||
}
|
||||
}
|
||||
result = modBusRtuClient.Write(address, coil, stationNumber);
|
||||
result = client.Write(address, coil, stationNumber);
|
||||
}
|
||||
else if (rd_short.Checked)
|
||||
{
|
||||
result = modBusRtuClient.Write(address, short.Parse(txt_value.Text?.Trim()), stationNumber);
|
||||
result = client.Write(address, short.Parse(txt_value.Text?.Trim()), stationNumber);
|
||||
}
|
||||
else if (rd_ushort.Checked)
|
||||
{
|
||||
result = modBusRtuClient.Write(address, ushort.Parse(txt_value.Text?.Trim()), stationNumber);
|
||||
result = client.Write(address, ushort.Parse(txt_value.Text?.Trim()), stationNumber);
|
||||
}
|
||||
else if (rd_int.Checked)
|
||||
{
|
||||
result = modBusRtuClient.Write(address, int.Parse(txt_value.Text?.Trim()), stationNumber);
|
||||
result = client.Write(address, int.Parse(txt_value.Text?.Trim()), stationNumber);
|
||||
}
|
||||
else if (rd_uint.Checked)
|
||||
{
|
||||
result = modBusRtuClient.Write(address, uint.Parse(txt_value.Text?.Trim()), stationNumber);
|
||||
result = client.Write(address, uint.Parse(txt_value.Text?.Trim()), stationNumber);
|
||||
}
|
||||
else if (rd_long.Checked)
|
||||
{
|
||||
result = modBusRtuClient.Write(address, long.Parse(txt_value.Text?.Trim()), stationNumber);
|
||||
result = client.Write(address, long.Parse(txt_value.Text?.Trim()), stationNumber);
|
||||
}
|
||||
else if (rd_ulong.Checked)
|
||||
{
|
||||
result = modBusRtuClient.Write(address, ulong.Parse(txt_value.Text?.Trim()), stationNumber);
|
||||
result = client.Write(address, ulong.Parse(txt_value.Text?.Trim()), stationNumber);
|
||||
}
|
||||
else if (rd_float.Checked)
|
||||
{
|
||||
result = modBusRtuClient.Write(address, float.Parse(txt_value.Text?.Trim()), stationNumber);
|
||||
result = client.Write(address, float.Parse(txt_value.Text?.Trim()), stationNumber);
|
||||
}
|
||||
else if (rd_double.Checked)
|
||||
{
|
||||
result = modBusRtuClient.Write(address, double.Parse(txt_value.Text?.Trim()), stationNumber);
|
||||
}
|
||||
result = client.Write(address, double.Parse(txt_value.Text?.Trim()), stationNumber);
|
||||
}
|
||||
else if (rd_discrete.Checked)
|
||||
{
|
||||
txt_content.AppendText($"[{DateTime.Now.ToLongTimeString()}]离散类型只读\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.IsSucceed)
|
||||
txt_content.AppendText($"[{DateTime.Now.ToLongTimeString()}][写入 {address?.Trim()} 成功]:{txt_value.Text?.Trim()} OK\r\n");
|
||||
|
@ -170,76 +256,53 @@ namespace IoTClient.Tool.Controls
|
|||
}
|
||||
}
|
||||
|
||||
private void butClose_Click(object sender, EventArgs e)
|
||||
/// <summary>
|
||||
/// 启动仿真服务
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void but_open_server_Click(object sender, EventArgs e)
|
||||
{
|
||||
modBusRtuClient?.Close();
|
||||
AppendText("关闭连接");
|
||||
but_open.Enabled = true;
|
||||
but_close.Enabled = false;
|
||||
}
|
||||
|
||||
private void but_read_Click(object sender, EventArgs e)
|
||||
{
|
||||
byte.TryParse(txt_stationNumber.Text?.Trim(), out byte stationNumber);
|
||||
if (string.IsNullOrWhiteSpace(txt_address.Text))
|
||||
{
|
||||
MessageBox.Show("请输入地址");
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
dynamic result = null;
|
||||
if (rd_bit.Checked)
|
||||
{
|
||||
result = modBusRtuClient.ReadCoil(txt_address.Text, stationNumber);
|
||||
}
|
||||
else if (rd_short.Checked)
|
||||
{
|
||||
result = modBusRtuClient.ReadInt16(txt_address.Text, stationNumber);
|
||||
}
|
||||
else if (rd_ushort.Checked)
|
||||
{
|
||||
result = modBusRtuClient.ReadUInt16(txt_address.Text, stationNumber);
|
||||
}
|
||||
else if (rd_int.Checked)
|
||||
{
|
||||
result = modBusRtuClient.ReadInt32(txt_address.Text, stationNumber);
|
||||
}
|
||||
else if (rd_uint.Checked)
|
||||
{
|
||||
result = modBusRtuClient.ReadUInt32(txt_address.Text, stationNumber);
|
||||
}
|
||||
else if (rd_long.Checked)
|
||||
{
|
||||
result = modBusRtuClient.ReadInt64(txt_address.Text, stationNumber);
|
||||
}
|
||||
else if (rd_ulong.Checked)
|
||||
{
|
||||
result = modBusRtuClient.ReadUInt64(txt_address.Text, stationNumber);
|
||||
}
|
||||
else if (rd_float.Checked)
|
||||
{
|
||||
result = modBusRtuClient.ReadFloat(txt_address.Text, stationNumber);
|
||||
}
|
||||
else if (rd_double.Checked)
|
||||
{
|
||||
result = modBusRtuClient.ReadDouble(txt_address.Text, stationNumber);
|
||||
}
|
||||
|
||||
if (result.IsSucceed)
|
||||
txt_content.AppendText($"[{DateTime.Now.ToLongTimeString()}][读取 {txt_address.Text?.Trim()} 成功]:{result.Value}\r\n");
|
||||
else
|
||||
txt_content.AppendText($"[{DateTime.Now.ToLongTimeString()}][读取 {txt_address.Text?.Trim()} 失败]:{result.Err}\r\n");
|
||||
if (checkBox1.Checked)
|
||||
{
|
||||
txt_content.AppendText($"[请求报文]{result.Requst}\r\n");
|
||||
txt_content.AppendText($"[响应报文]{result.Response}\r\n\r\n");
|
||||
}
|
||||
var PortName = cb_portNameSend_server.Text.ToString();
|
||||
var BaudRate = int.Parse(txt_baudRate.Text.ToString());
|
||||
var DataBits = int.Parse(txt_dataBit.Text.ToString());
|
||||
var StopBits = (StopBits)int.Parse(txt_stopBit.Text.ToString());
|
||||
server?.Stop();
|
||||
server = new ModBusRtuServer(PortName, BaudRate, DataBits, StopBits);
|
||||
server.Start();
|
||||
AppendText("开启仿真服务");
|
||||
but_server_open.Enabled = false;
|
||||
but_server_close.Enabled = true;
|
||||
cb_portNameSend_server.Enabled = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭仿真服务
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void but_close_server_Click(object sender, EventArgs e)
|
||||
{
|
||||
server?.Stop();
|
||||
AppendText("关闭仿真服务");
|
||||
but_server_open.Enabled = true;
|
||||
but_server_close.Enabled = false;
|
||||
cb_portNameSend_server.Enabled = true;
|
||||
}
|
||||
|
||||
private void AppendText(string content)
|
||||
{
|
||||
txt_content.Invoke((Action)(() =>
|
||||
{
|
||||
txt_content.AppendText($"[{DateTime.Now.ToLongTimeString()}]{content}\r\n");
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
29
IoTClient.Tool/Controls/ModBusTcpControl.Designer.cs
generated
29
IoTClient.Tool/Controls/ModBusTcpControl.Designer.cs
generated
|
@ -61,6 +61,7 @@
|
|||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.txt_content = new System.Windows.Forms.TextBox();
|
||||
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.rd_discrete = new System.Windows.Forms.RadioButton();
|
||||
this.groupBox2.SuspendLayout();
|
||||
this.groupBox1.SuspendLayout();
|
||||
this.groupBox3.SuspendLayout();
|
||||
|
@ -187,6 +188,7 @@
|
|||
//
|
||||
// groupBox1
|
||||
//
|
||||
this.groupBox1.Controls.Add(this.rd_discrete);
|
||||
this.groupBox1.Controls.Add(this.button6);
|
||||
this.groupBox1.Controls.Add(this.rd_float);
|
||||
this.groupBox1.Controls.Add(this.rd_double);
|
||||
|
@ -216,7 +218,7 @@
|
|||
// rd_float
|
||||
//
|
||||
this.rd_float.AutoSize = true;
|
||||
this.rd_float.Location = new System.Drawing.Point(436, 23);
|
||||
this.rd_float.Location = new System.Drawing.Point(486, 23);
|
||||
this.rd_float.Name = "rd_float";
|
||||
this.rd_float.Size = new System.Drawing.Size(53, 16);
|
||||
this.rd_float.TabIndex = 22;
|
||||
|
@ -226,7 +228,7 @@
|
|||
// rd_double
|
||||
//
|
||||
this.rd_double.AutoSize = true;
|
||||
this.rd_double.Location = new System.Drawing.Point(495, 23);
|
||||
this.rd_double.Location = new System.Drawing.Point(545, 23);
|
||||
this.rd_double.Name = "rd_double";
|
||||
this.rd_double.Size = new System.Drawing.Size(59, 16);
|
||||
this.rd_double.TabIndex = 23;
|
||||
|
@ -237,7 +239,7 @@
|
|||
//
|
||||
this.rd_short.AutoSize = true;
|
||||
this.rd_short.Checked = true;
|
||||
this.rd_short.Location = new System.Drawing.Point(70, 23);
|
||||
this.rd_short.Location = new System.Drawing.Point(120, 23);
|
||||
this.rd_short.Name = "rd_short";
|
||||
this.rd_short.Size = new System.Drawing.Size(53, 16);
|
||||
this.rd_short.TabIndex = 6;
|
||||
|
@ -258,7 +260,7 @@
|
|||
// rd_ulong
|
||||
//
|
||||
this.rd_ulong.AutoSize = true;
|
||||
this.rd_ulong.Location = new System.Drawing.Point(374, 23);
|
||||
this.rd_ulong.Location = new System.Drawing.Point(424, 23);
|
||||
this.rd_ulong.Name = "rd_ulong";
|
||||
this.rd_ulong.Size = new System.Drawing.Size(53, 16);
|
||||
this.rd_ulong.TabIndex = 21;
|
||||
|
@ -268,7 +270,7 @@
|
|||
// rd_ushort
|
||||
//
|
||||
this.rd_ushort.AutoSize = true;
|
||||
this.rd_ushort.Location = new System.Drawing.Point(129, 23);
|
||||
this.rd_ushort.Location = new System.Drawing.Point(179, 23);
|
||||
this.rd_ushort.Name = "rd_ushort";
|
||||
this.rd_ushort.Size = new System.Drawing.Size(59, 16);
|
||||
this.rd_ushort.TabIndex = 17;
|
||||
|
@ -278,7 +280,7 @@
|
|||
// rd_long
|
||||
//
|
||||
this.rd_long.AutoSize = true;
|
||||
this.rd_long.Location = new System.Drawing.Point(315, 23);
|
||||
this.rd_long.Location = new System.Drawing.Point(365, 23);
|
||||
this.rd_long.Name = "rd_long";
|
||||
this.rd_long.Size = new System.Drawing.Size(47, 16);
|
||||
this.rd_long.TabIndex = 20;
|
||||
|
@ -288,7 +290,7 @@
|
|||
// rd_int
|
||||
//
|
||||
this.rd_int.AutoSize = true;
|
||||
this.rd_int.Location = new System.Drawing.Point(194, 23);
|
||||
this.rd_int.Location = new System.Drawing.Point(244, 23);
|
||||
this.rd_int.Name = "rd_int";
|
||||
this.rd_int.Size = new System.Drawing.Size(41, 16);
|
||||
this.rd_int.TabIndex = 18;
|
||||
|
@ -298,7 +300,7 @@
|
|||
// rd_uint
|
||||
//
|
||||
this.rd_uint.AutoSize = true;
|
||||
this.rd_uint.Location = new System.Drawing.Point(253, 23);
|
||||
this.rd_uint.Location = new System.Drawing.Point(303, 23);
|
||||
this.rd_uint.Name = "rd_uint";
|
||||
this.rd_uint.Size = new System.Drawing.Size(47, 16);
|
||||
this.rd_uint.TabIndex = 19;
|
||||
|
@ -382,6 +384,16 @@
|
|||
this.txt_content.Size = new System.Drawing.Size(855, 272);
|
||||
this.txt_content.TabIndex = 27;
|
||||
//
|
||||
// radioButton1
|
||||
//
|
||||
this.rd_discrete.AutoSize = true;
|
||||
this.rd_discrete.Location = new System.Drawing.Point(64, 23);
|
||||
this.rd_discrete.Name = "radioButton1";
|
||||
this.rd_discrete.Size = new System.Drawing.Size(47, 16);
|
||||
this.rd_discrete.TabIndex = 24;
|
||||
this.rd_discrete.Text = "离散";
|
||||
this.rd_discrete.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// ModBusTcpControl
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
|
||||
|
@ -437,5 +449,6 @@
|
|||
private System.Windows.Forms.Button button2;
|
||||
private System.Windows.Forms.Button button5;
|
||||
private System.Windows.Forms.Button button6;
|
||||
private System.Windows.Forms.RadioButton rd_discrete;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace IoTClient.Tool
|
|||
|
||||
private void button1_Click(object sender, EventArgs e)
|
||||
{
|
||||
server?.Close();
|
||||
server?.Stop();
|
||||
server = new ModBusTcpServer(502);
|
||||
server.Start();
|
||||
button1.Enabled = false;
|
||||
|
@ -42,7 +42,7 @@ namespace IoTClient.Tool
|
|||
|
||||
private void button2_Click(object sender, EventArgs e)
|
||||
{
|
||||
server?.Close();
|
||||
server?.Stop();
|
||||
button1.Enabled = true;
|
||||
button2.Enabled = false;
|
||||
txt_content.AppendText($"[{DateTime.Now.ToLongTimeString()}]关闭仿真模拟服务\r\n");
|
||||
|
@ -120,6 +120,10 @@ namespace IoTClient.Tool
|
|||
{
|
||||
result = client.ReadDouble(txt_address.Text, stationNumber);
|
||||
}
|
||||
else if (rd_discrete.Checked)
|
||||
{
|
||||
result = client.ReadDiscrete(txt_address.Text, stationNumber);
|
||||
}
|
||||
|
||||
if (result.IsSucceed)
|
||||
txt_content.AppendText($"[{DateTime.Now.ToLongTimeString()}][读取 {txt_address.Text?.Trim()} 成功]:{result.Value}\r\n");
|
||||
|
@ -202,7 +206,11 @@ namespace IoTClient.Tool
|
|||
{
|
||||
result = client.Write(txt_address.Text, double.Parse(txt_value.Text?.Trim()), stationNumber);
|
||||
}
|
||||
|
||||
else if (rd_discrete.Checked)
|
||||
{
|
||||
txt_content.AppendText($"[{DateTime.Now.ToLongTimeString()}]离散类型只读\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.IsSucceed)
|
||||
txt_content.AppendText($"[{DateTime.Now.ToLongTimeString()}][写入 {txt_address.Text?.Trim()} 成功]:{txt_value.Text?.Trim()} OK\r\n");
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace IoTClient.Tool
|
|||
|
||||
private void but_server_Click(object sender, EventArgs e)
|
||||
{
|
||||
server?.Close();
|
||||
server?.Stop();
|
||||
server = new SiemensServer(int.Parse(txt_port.Text.Trim()));
|
||||
server.Start();
|
||||
but_server.Enabled = false;
|
||||
|
@ -41,7 +41,7 @@ namespace IoTClient.Tool
|
|||
|
||||
private void button2_Click(object sender, EventArgs e)
|
||||
{
|
||||
server?.Close();
|
||||
server?.Stop();
|
||||
but_server.Enabled = true;
|
||||
button2.Enabled = false;
|
||||
txt_content.AppendText($"[{DateTime.Now.ToLongTimeString()}]关闭仿真模拟服务\r\n");
|
||||
|
|
4
IoTClient.Tool/IndexForm.Designer.cs
generated
4
IoTClient.Tool/IndexForm.Designer.cs
generated
|
@ -182,8 +182,8 @@
|
|||
//
|
||||
this.toolStripMenuItem1.ForeColor = System.Drawing.Color.White;
|
||||
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
|
||||
this.toolStripMenuItem1.Size = new System.Drawing.Size(87, 21);
|
||||
this.toolStripMenuItem1.Text = "测试版 0.0.3";
|
||||
this.toolStripMenuItem1.Size = new System.Drawing.Size(75, 21);
|
||||
this.toolStripMenuItem1.Text = "版本 0.0.3";
|
||||
this.toolStripMenuItem1.Click += new System.EventHandler(this.toolStripMenuItem1_Click);
|
||||
//
|
||||
// IndexForm
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using IoTClient.Common.Helpers;
|
||||
using IoTClient.Core;
|
||||
using IoTClient.Models;
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
using System.Linq;
|
||||
|
@ -47,7 +47,7 @@ namespace IoTClient.Clients.ModBus
|
|||
/// 获取设备上的COM端口集合
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string[] GetPortNames()
|
||||
public static string[] GetPortNames()
|
||||
{
|
||||
return SerialPort.GetPortNames();
|
||||
}
|
||||
|
@ -138,6 +138,19 @@ namespace IoTClient.Clients.ModBus
|
|||
|
||||
//3 获取响应报文
|
||||
var responsePackage = SerialPortRead(serialPort);
|
||||
if (!responsePackage.Any())
|
||||
{
|
||||
result.IsSucceed = false;
|
||||
result.Err = "响应结果为空,请检查是否连上了服务端";
|
||||
return result;
|
||||
}
|
||||
else if (!CRC16.CheckCRC16(responsePackage))
|
||||
{
|
||||
result.IsSucceed = false;
|
||||
result.Err = "响应结果CRC16验证失败";
|
||||
return result;
|
||||
}
|
||||
|
||||
byte[] resultData = new byte[responsePackage.Length - 2];
|
||||
Array.Copy(responsePackage, 0, resultData, 0, resultData.Length);
|
||||
|
||||
|
@ -363,7 +376,30 @@ namespace IoTClient.Clients.ModBus
|
|||
if (result.IsSucceed)
|
||||
result.Value = BitConverter.ToBoolean(readResut.Value, 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取离散
|
||||
/// </summary>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="stationNumber"></param>
|
||||
/// <param name="functionCode"></param>
|
||||
/// <returns></returns>
|
||||
public Result<bool> ReadDiscrete(string address, byte stationNumber = 1, byte functionCode = 2)
|
||||
{
|
||||
var readResut = Read(address, stationNumber, functionCode);
|
||||
var result = new Result<bool>()
|
||||
{
|
||||
IsSucceed = readResut.IsSucceed,
|
||||
Err = readResut.Err,
|
||||
ErrList = readResut.ErrList,
|
||||
Requst = readResut.Requst,
|
||||
Response = readResut.Response,
|
||||
};
|
||||
if (result.IsSucceed)
|
||||
result.Value = BitConverter.ToBoolean(readResut.Value, 0);
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Write 写入
|
||||
|
@ -385,10 +421,16 @@ namespace IoTClient.Clients.ModBus
|
|||
serialPort.Write(commandCRC16, 0, commandCRC16.Length);
|
||||
result.Requst = string.Join(" ", commandCRC16.Select(t => t.ToString("X2")));
|
||||
//3 获取响应报文
|
||||
var dataPackage = SerialPortRead(serialPort);
|
||||
byte[] resultBuffer = new byte[dataPackage.Length - 2];
|
||||
Array.Copy(dataPackage, 0, resultBuffer, 0, resultBuffer.Length);
|
||||
result.Response = string.Join(" ", dataPackage.Select(t => t.ToString("X2")));
|
||||
var responsePackage = SerialPortRead(serialPort);
|
||||
if (!CRC16.CheckCRC16(responsePackage))
|
||||
{
|
||||
result.IsSucceed = false;
|
||||
result.Err = "响应结果CRC16验证失败";
|
||||
return result;
|
||||
}
|
||||
byte[] resultBuffer = new byte[responsePackage.Length - 2];
|
||||
Array.Copy(responsePackage, 0, resultBuffer, 0, resultBuffer.Length);
|
||||
result.Response = string.Join(" ", responsePackage.Select(t => t.ToString("X2")));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -424,10 +466,16 @@ namespace IoTClient.Clients.ModBus
|
|||
serialPort.Write(commandCRC16, 0, commandCRC16.Length);
|
||||
result.Requst = string.Join(" ", commandCRC16.Select(t => t.ToString("X2")));
|
||||
//3 获取响应报文
|
||||
var dataPackage = SerialPortRead(serialPort);
|
||||
byte[] resultBuffer = new byte[dataPackage.Length - 2];
|
||||
Array.Copy(dataPackage, 0, resultBuffer, 0, resultBuffer.Length);
|
||||
result.Response = string.Join(" ", dataPackage.Select(t => t.ToString("X2")));
|
||||
var responsePackage = SerialPortRead(serialPort);
|
||||
if (!CRC16.CheckCRC16(responsePackage))
|
||||
{
|
||||
result.IsSucceed = false;
|
||||
result.Err = "响应结果CRC16验证失败";
|
||||
return result;
|
||||
}
|
||||
byte[] resultBuffer = new byte[responsePackage.Length - 2];
|
||||
Array.Copy(responsePackage, 0, resultBuffer, 0, resultBuffer.Length);
|
||||
result.Response = string.Join(" ", responsePackage.Select(t => t.ToString("X2")));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using IoTClient.Core;
|
||||
using IoTClient.Models;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
|
@ -73,8 +74,9 @@ namespace IoTClient.Clients.ModBus
|
|||
var result = new Result<byte[]>();
|
||||
try
|
||||
{
|
||||
var chenkHead = GetCheckHead(functionCode);
|
||||
//1 获取命令(组装报文)
|
||||
byte[] command = GetReadCommand(address, stationNumber, functionCode, readLength);
|
||||
byte[] command = GetReadCommand(address, stationNumber, functionCode, readLength, chenkHead);
|
||||
result.Requst = string.Join(" ", command.Select(t => t.ToString("X2")));
|
||||
//2 发送命令
|
||||
socket.Send(command);
|
||||
|
@ -82,13 +84,17 @@ namespace IoTClient.Clients.ModBus
|
|||
var headPackage = SocketRead(socket, 8);
|
||||
int length = headPackage[4] * 256 + headPackage[5] - 2;
|
||||
var dataPackage = SocketRead(socket, length);
|
||||
|
||||
byte[] resultBuffer = new byte[dataPackage.Length - 1];
|
||||
Array.Copy(dataPackage, 1, resultBuffer, 0, resultBuffer.Length);
|
||||
|
||||
result.Response = string.Join(" ", headPackage.Concat(dataPackage).Select(t => t.ToString("X2")));
|
||||
//4 获取响应报文数据(字节数组形式)
|
||||
result.Value = resultBuffer.Reverse().ToArray();
|
||||
if (chenkHead[0] != headPackage[0] || chenkHead[1] != headPackage[1])
|
||||
{
|
||||
result.IsSucceed = false;
|
||||
result.Err = "响应结果校验失败";
|
||||
result.ErrList.Add("响应结果校验失败");
|
||||
}
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
|
@ -319,6 +325,29 @@ namespace IoTClient.Clients.ModBus
|
|||
result.Value = BitConverter.ToBoolean(readResut.Value, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取离散
|
||||
/// </summary>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="stationNumber"></param>
|
||||
/// <param name="functionCode"></param>
|
||||
/// <returns></returns>
|
||||
public Result<bool> ReadDiscrete(string address, byte stationNumber = 1, byte functionCode = 2)
|
||||
{
|
||||
var readResut = Read(address, stationNumber, functionCode);
|
||||
var result = new Result<bool>()
|
||||
{
|
||||
IsSucceed = readResut.IsSucceed,
|
||||
Err = readResut.Err,
|
||||
ErrList = readResut.ErrList,
|
||||
Requst = readResut.Requst,
|
||||
Response = readResut.Response,
|
||||
};
|
||||
if (result.IsSucceed)
|
||||
result.Value = BitConverter.ToBoolean(readResut.Value, 0);
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Write 写入
|
||||
|
@ -336,14 +365,21 @@ namespace IoTClient.Clients.ModBus
|
|||
var result = new Result();
|
||||
try
|
||||
{
|
||||
var command = GetWriteCoilCommand(address, value, stationNumber, functionCode);
|
||||
var chenkHead = GetCheckHead(functionCode);
|
||||
var command = GetWriteCoilCommand(address, value, stationNumber, functionCode, chenkHead);
|
||||
socket.Send(command);
|
||||
result.Requst = string.Join(" ", command.Select(t => t.ToString("X2")));
|
||||
//获取响应报文
|
||||
var headBytes = SocketRead(socket, 8);
|
||||
int length = headBytes[4] * 256 + headBytes[5] - 2;
|
||||
var dataBytes = SocketRead(socket, length);
|
||||
result.Response = string.Join(" ", headBytes.Concat(dataBytes).Select(t => t.ToString("X2")));
|
||||
var headPackage = SocketRead(socket, 8);
|
||||
int length = headPackage[4] * 256 + headPackage[5] - 2;
|
||||
var dataPackage = SocketRead(socket, length);
|
||||
result.Response = string.Join(" ", headPackage.Concat(dataPackage).Select(t => t.ToString("X2")));
|
||||
if (chenkHead[0] != headPackage[0] || chenkHead[1] != headPackage[1])
|
||||
{
|
||||
result.IsSucceed = false;
|
||||
result.Err = "响应结果校验失败";
|
||||
result.ErrList.Add("响应结果校验失败");
|
||||
}
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
|
@ -383,14 +419,21 @@ namespace IoTClient.Clients.ModBus
|
|||
var result = new Result();
|
||||
try
|
||||
{
|
||||
var command = GetWriteCommand(address, values, stationNumber, functionCode);
|
||||
var chenkHead = GetCheckHead(functionCode);
|
||||
var command = GetWriteCommand(address, values, stationNumber, functionCode, chenkHead);
|
||||
socket.Send(command);
|
||||
result.Requst = string.Join(" ", command.Select(t => t.ToString("X2")));
|
||||
//获取响应报文
|
||||
var headBytes = SocketRead(socket, 8);
|
||||
int length = headBytes[4] * 256 + headBytes[5] - 2;
|
||||
var dataBytes = SocketRead(socket, length);
|
||||
result.Response = string.Join(" ", headBytes.Concat(dataBytes).Select(t => t.ToString("X2")));
|
||||
var headPackage = SocketRead(socket, 8);
|
||||
int length = headPackage[4] * 256 + headPackage[5] - 2;
|
||||
var dataPackage = SocketRead(socket, length);
|
||||
result.Response = string.Join(" ", headPackage.Concat(dataPackage).Select(t => t.ToString("X2")));
|
||||
if (chenkHead[0] != headPackage[0] || chenkHead[1] != headPackage[1])
|
||||
{
|
||||
result.IsSucceed = false;
|
||||
result.Err = "响应结果校验失败";
|
||||
result.ErrList.Add("响应结果校验失败");
|
||||
}
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
|
@ -522,6 +565,16 @@ namespace IoTClient.Clients.ModBus
|
|||
|
||||
#region 获取命令
|
||||
|
||||
/// <summary>
|
||||
/// 获取随机校验头
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private byte[] GetCheckHead(int seed)
|
||||
{
|
||||
var random = new Random(DateTime.Now.Millisecond + seed);
|
||||
return new byte[] { (byte)random.Next(255), (byte)random.Next(255) };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取读取命令
|
||||
/// </summary>
|
||||
|
@ -530,12 +583,12 @@ namespace IoTClient.Clients.ModBus
|
|||
/// <param name="functionCode">功能码</param>
|
||||
/// <param name="length">读取长度</param>
|
||||
/// <returns></returns>
|
||||
public byte[] GetReadCommand(string address, byte stationNumber, byte functionCode, ushort length)
|
||||
public byte[] GetReadCommand(string address, byte stationNumber, byte functionCode, ushort length, byte[] check = null)
|
||||
{
|
||||
var readAddress = ushort.Parse(address?.Trim());
|
||||
byte[] buffer = new byte[12];
|
||||
buffer[0] = 0x19;
|
||||
buffer[1] = 0xB2;//Client发出的检验信息
|
||||
buffer[0] = check?[0] ?? 0x19;
|
||||
buffer[1] = check?[1] ?? 0xB2;//Client发出的检验信息
|
||||
buffer[2] = 0x00;
|
||||
buffer[3] = 0x00;//表示tcp/ip 的协议的modbus的协议
|
||||
buffer[4] = 0x00;
|
||||
|
@ -558,12 +611,12 @@ namespace IoTClient.Clients.ModBus
|
|||
/// <param name="stationNumber">站号</param>
|
||||
/// <param name="functionCode">功能码</param>
|
||||
/// <returns></returns>
|
||||
public byte[] GetWriteCommand(string address, byte[] values, byte stationNumber, byte functionCode)
|
||||
public byte[] GetWriteCommand(string address, byte[] values, byte stationNumber, byte functionCode, byte[] check = null)
|
||||
{
|
||||
var writeAddress = ushort.Parse(address?.Trim());
|
||||
byte[] buffer = new byte[13 + values.Length];
|
||||
buffer[0] = 0x19;
|
||||
buffer[1] = 0xB2;//检验信息,用来验证response是否串数据了
|
||||
buffer[0] = check?[0] ?? 0x19;
|
||||
buffer[1] = check?[1] ?? 0xB2;//检验信息,用来验证response是否串数据了
|
||||
buffer[4] = BitConverter.GetBytes(7 + values.Length)[1];
|
||||
buffer[5] = BitConverter.GetBytes(7 + values.Length)[0];//表示的是header handle后面还有多长的字节
|
||||
|
||||
|
@ -586,12 +639,12 @@ namespace IoTClient.Clients.ModBus
|
|||
/// <param name="stationNumber">站号</param>
|
||||
/// <param name="functionCode">功能码</param>
|
||||
/// <returns></returns>
|
||||
public byte[] GetWriteCoilCommand(string address, bool value, byte stationNumber, byte functionCode)
|
||||
public byte[] GetWriteCoilCommand(string address, bool value, byte stationNumber, byte functionCode, byte[] check = null)
|
||||
{
|
||||
var writeAddress = ushort.Parse(address?.Trim());
|
||||
byte[] buffer = new byte[12];
|
||||
buffer[0] = 0x19;
|
||||
buffer[1] = 0xB2;//Client发出的检验信息
|
||||
buffer[0] = check?[0] ?? 0x19;
|
||||
buffer[1] = check?[1] ?? 0xB2;//Client发出的检验信息
|
||||
buffer[4] = 0x00;
|
||||
buffer[5] = 0x06;//表示的是该字节以后的字节长度
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using IoTClient.Common.Enums;
|
||||
using IoTClient.Core;
|
||||
using IoTClient.Core.Models;
|
||||
using IoTClient.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
|
|
@ -149,6 +149,15 @@
|
|||
<param name="functionCode">功能码</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.ModBus.ModBusRtuClient.ReadDiscrete(System.String,System.Byte,System.Byte)">
|
||||
<summary>
|
||||
读取离散
|
||||
</summary>
|
||||
<param name="address"></param>
|
||||
<param name="stationNumber"></param>
|
||||
<param name="functionCode"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.ModBus.ModBusRtuClient.Write(System.String,System.Boolean,System.Byte,System.Byte)">
|
||||
<summary>
|
||||
线圈写入
|
||||
|
@ -379,6 +388,15 @@
|
|||
<param name="functionCode">功能码</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.ModBus.ModBusTcpClient.ReadDiscrete(System.String,System.Byte,System.Byte)">
|
||||
<summary>
|
||||
读取离散
|
||||
</summary>
|
||||
<param name="address"></param>
|
||||
<param name="stationNumber"></param>
|
||||
<param name="functionCode"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.ModBus.ModBusTcpClient.Write(System.String,System.Boolean,System.Byte,System.Byte)">
|
||||
<summary>
|
||||
线圈写入
|
||||
|
@ -470,7 +488,13 @@
|
|||
<param name="stationNumber">站号</param>
|
||||
<param name="functionCode">功能码</param>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.ModBus.ModBusTcpClient.GetReadCommand(System.String,System.Byte,System.Byte,System.UInt16)">
|
||||
<member name="M:IoTClient.Clients.ModBus.ModBusTcpClient.GetCheckHead(System.Int32)">
|
||||
<summary>
|
||||
获取随机校验头
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.ModBus.ModBusTcpClient.GetReadCommand(System.String,System.Byte,System.Byte,System.UInt16,System.Byte[])">
|
||||
<summary>
|
||||
获取读取命令
|
||||
</summary>
|
||||
|
@ -480,7 +504,7 @@
|
|||
<param name="length">读取长度</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.ModBus.ModBusTcpClient.GetWriteCommand(System.String,System.Byte[],System.Byte,System.Byte)">
|
||||
<member name="M:IoTClient.Clients.ModBus.ModBusTcpClient.GetWriteCommand(System.String,System.Byte[],System.Byte,System.Byte,System.Byte[])">
|
||||
<summary>
|
||||
获取写入命令
|
||||
</summary>
|
||||
|
@ -490,7 +514,7 @@
|
|||
<param name="functionCode">功能码</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IoTClient.Clients.ModBus.ModBusTcpClient.GetWriteCoilCommand(System.String,System.Boolean,System.Byte,System.Byte)">
|
||||
<member name="M:IoTClient.Clients.ModBus.ModBusTcpClient.GetWriteCoilCommand(System.String,System.Boolean,System.Byte,System.Byte,System.Byte[])">
|
||||
<summary>
|
||||
获取线圈写入命令
|
||||
</summary>
|
||||
|
@ -805,42 +829,42 @@
|
|||
西门子S7-200Smar
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:IoTClient.Core.Result">
|
||||
<member name="T:IoTClient.Models.Result">
|
||||
<summary>
|
||||
请求结果
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IoTClient.Core.Result.IsSucceed">
|
||||
<member name="P:IoTClient.Models.Result.IsSucceed">
|
||||
<summary>
|
||||
是否成功
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IoTClient.Core.Result.Err">
|
||||
<member name="P:IoTClient.Models.Result.Err">
|
||||
<summary>
|
||||
异常消息
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IoTClient.Core.Result.ErrList">
|
||||
<member name="P:IoTClient.Models.Result.ErrList">
|
||||
<summary>
|
||||
异常集合
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IoTClient.Core.Result.Requst">
|
||||
<member name="P:IoTClient.Models.Result.Requst">
|
||||
<summary>
|
||||
请求报文
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IoTClient.Core.Result.Response">
|
||||
<member name="P:IoTClient.Models.Result.Response">
|
||||
<summary>
|
||||
响应报文
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:IoTClient.Core.Result`1">
|
||||
<member name="T:IoTClient.Models.Result`1">
|
||||
<summary>
|
||||
请求结果
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IoTClient.Core.Result`1.Value">
|
||||
<member name="P:IoTClient.Models.Result`1.Value">
|
||||
<summary>
|
||||
数据结果
|
||||
</summary>
|
||||
|
|
61
IoTClient/Models/Result.cs
Normal file
61
IoTClient/Models/Result.cs
Normal file
|
@ -0,0 +1,61 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace IoTClient.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 请求结果
|
||||
/// </summary>
|
||||
public class Result
|
||||
{
|
||||
public Result()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否成功
|
||||
/// </summary>
|
||||
public bool IsSucceed { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 异常消息
|
||||
/// </summary>
|
||||
public string Err { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 异常集合
|
||||
/// </summary>
|
||||
public List<string> ErrList { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 请求报文
|
||||
/// </summary>
|
||||
public string Requst { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 响应报文
|
||||
/// </summary>
|
||||
public string Response { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 请求结果
|
||||
/// </summary>
|
||||
public class Result<T> : Result
|
||||
{
|
||||
public Result()
|
||||
{
|
||||
}
|
||||
|
||||
public Result(T data)
|
||||
{
|
||||
Value = data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数据结果
|
||||
/// </summary>
|
||||
public T Value { get; set; }
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,8 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace IoTClient.Core.Models
|
||||
namespace IoTClient.Core.Models
|
||||
{
|
||||
public class SiemensData
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using IoTClient.Models;
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace IoTClient.Core
|
||||
|
|
|
@ -39,11 +39,33 @@
|
|||
初始化加载数据
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IoTServer.Servers.ModBus.ModBusRtuServer.Start">
|
||||
<summary>
|
||||
启动服务
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IoTServer.Servers.ModBus.ModBusRtuServer.Stop">
|
||||
<summary>
|
||||
停止服务
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IoTServer.Servers.ModBus.ModBusRtuServer.DataReceived(System.Object,System.IO.Ports.SerialDataReceivedEventArgs)">
|
||||
<summary>
|
||||
接收数据回调用
|
||||
</summary>
|
||||
<param name="sender"></param>
|
||||
<param name="e"></param>
|
||||
</member>
|
||||
<member name="M:IoTServer.Servers.ModBus.ModBusTcpServer.Start">
|
||||
<summary>
|
||||
启动服务
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IoTServer.Servers.ModBus.ModBusTcpServer.Stop">
|
||||
<summary>
|
||||
停止服务
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IoTServer.Servers.ModBus.ModBusTcpServer.Accept(System.Net.Sockets.Socket)">
|
||||
<summary>
|
||||
客户端连接到服务端
|
||||
|
@ -61,6 +83,11 @@
|
|||
启动服务
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IoTServer.Servers.PLC.SiemensServer.Stop">
|
||||
<summary>
|
||||
停止服务
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IoTServer.Servers.PLC.SiemensServer.Accept(System.Net.Sockets.Socket)">
|
||||
<summary>
|
||||
客户端连接到服务端
|
||||
|
|
117
IoTServer/Servers/ModBus/ModBusRtuServer.cs
Normal file
117
IoTServer/Servers/ModBus/ModBusRtuServer.cs
Normal file
|
@ -0,0 +1,117 @@
|
|||
using IoTClient.Common.Helpers;
|
||||
using IoTServer.Common;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace IoTServer.Servers.ModBus
|
||||
{
|
||||
public class ModBusRtuServer
|
||||
{
|
||||
private SerialPort serialPort;
|
||||
DataPersist dataPersist;
|
||||
public ModBusRtuServer(string portName, int baudRate, int dataBits, StopBits stopBits)
|
||||
{
|
||||
if (serialPort == null) serialPort = new SerialPort();
|
||||
serialPort.PortName = portName;
|
||||
serialPort.BaudRate = baudRate;
|
||||
serialPort.DataBits = dataBits;
|
||||
serialPort.StopBits = stopBits;
|
||||
serialPort.Encoding = Encoding.ASCII;
|
||||
#if !DEBUG
|
||||
serialPort.ReadTimeout = 1000;//1秒
|
||||
#endif
|
||||
serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceived);
|
||||
dataPersist = new DataPersist("ModBusTcpServer");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动服务
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
serialPort.Open();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止服务
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
serialPort.Close();
|
||||
serialPort.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 接收数据回调用
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void DataReceived(object sender, SerialDataReceivedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] requetData = new byte[serialPort.BytesToRead];
|
||||
serialPort.Read(requetData, 0, requetData.Length);
|
||||
var address = requetData[2] * 256 + requetData[3];
|
||||
switch (requetData[1])
|
||||
{
|
||||
//读取线圈
|
||||
case 1:
|
||||
{
|
||||
var value = dataPersist.Read(address);
|
||||
var bytes = JsonConvert.DeserializeObject<byte[]>(value).Reverse().ToArray();
|
||||
var tempData = new byte[4];
|
||||
tempData[0] = 1;
|
||||
tempData[1] = 1;
|
||||
Buffer.BlockCopy(bytes, 0, tempData, 2, 2);
|
||||
var responseData = CRC16.GetCRC16(tempData);
|
||||
serialPort.Write(responseData, 0, responseData.Length);
|
||||
}
|
||||
break;
|
||||
//写入线圈
|
||||
case 5:
|
||||
{
|
||||
var value = new byte[2];
|
||||
Buffer.BlockCopy(requetData, requetData.Length - 4, value, 0, value.Length);
|
||||
dataPersist.Write(address, JsonConvert.SerializeObject(value));
|
||||
serialPort.Write(requetData, 0, requetData.Length);
|
||||
}
|
||||
break;
|
||||
//读取
|
||||
case 3:
|
||||
{
|
||||
var value = dataPersist.Read(address);
|
||||
var bytes = JsonConvert.DeserializeObject<byte[]>(value);
|
||||
if (bytes == null)
|
||||
{
|
||||
var length = requetData[requetData.Length - 4] * 256 + requetData[requetData.Length - 5];
|
||||
bytes = new byte[length * 2];
|
||||
}
|
||||
var dataHead = new byte[] { 1, 3, (byte)bytes.Length };
|
||||
var tempData = dataHead.Concat(bytes).ToArray();
|
||||
var responseData = CRC16.GetCRC16(tempData);
|
||||
serialPort.Write(responseData, 0, responseData.Length);
|
||||
}
|
||||
break;
|
||||
//写入
|
||||
case 16:
|
||||
{
|
||||
var value = new byte[requetData[6]];
|
||||
Buffer.BlockCopy(requetData, 7, value, 0, value.Length);
|
||||
dataPersist.Write(address, JsonConvert.SerializeObject(value));
|
||||
var tempData = new byte[6];
|
||||
Buffer.BlockCopy(requetData, 0, tempData, 0, tempData.Length);
|
||||
var responseData = CRC16.GetCRC16(tempData);
|
||||
serialPort.Write(responseData, 0, responseData.Length);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -42,7 +42,10 @@ namespace IoTServer.Servers.ModBus
|
|||
Task.Run(() => { Accept(socketServer); });
|
||||
}
|
||||
|
||||
public void Close()
|
||||
/// <summary>
|
||||
/// 停止服务
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
if (socketServer?.Connected ?? false)
|
||||
socketServer.Shutdown(SocketShutdown.Both);
|
||||
|
@ -148,7 +151,6 @@ namespace IoTServer.Servers.ModBus
|
|||
//读取
|
||||
case 3:
|
||||
{
|
||||
|
||||
var value = dataPersist.Read(address);// 数据存在 8、9
|
||||
var bytes = JsonConvert.DeserializeObject<byte[]>(value);
|
||||
if (bytes == null)
|
||||
|
|
|
@ -44,7 +44,10 @@ namespace IoTServer.Servers.PLC
|
|||
Task.Run(() => { Accept(socketServer); });
|
||||
}
|
||||
|
||||
public void Close()
|
||||
/// <summary>
|
||||
/// 停止服务
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
if (socketServer?.Connected ?? false)
|
||||
socketServer.Shutdown(SocketShutdown.Both);
|
||||
|
|
12
README.md
12
README.md
|
@ -3,10 +3,14 @@
|
|||
QQ交流群:[995475200](https://jq.qq.com/?_wv=1027&k=5bz0ne5)
|
||||
|
||||
# Demo效果图
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
|
Loading…
Reference in New Issue
Block a user