1、依赖库:NModbus4
https://github.com/NModbus4/NModbus4
2、添加引用
using Modbus.Data;
using Modbus.Device;
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;
3、全局变量声明:
/// <summary>
/// 服务器提供的数据区
/// </summary>
public static DataStore Data;
/// <summary>
/// Modbus服务器
/// </summary>
public static ModbusSlave modbus_tcp_server;
4、创建ModbusTCP服务:
Data = DataStoreFactory.CreateDefaultDataStore(); //初始化服务数据区
modbus_tcp_server = ModbusTcpSlave.CreateTcp(1, new TcpListener(IPAddress.Parse("0.0.0.0"), 502)); //创建ModbusTcp服务器
modbus_tcp_server.DataStore = Data;//数据区赋值
modbus_tcp_server.ModbusSlaveRequestReceived += _modbusSlave_ModbusSlaveRequestReceived; //接收到查询的事件(供调试显示,非必须)
5、启动服务:(非阻塞方式)
Thread th_0 = new Thread(() =>
{
modbus_tcp_server.Listen();//异步 非阻塞 启动服务
})
{
IsBackground = true,
};
th_0.SetApartmentState(ApartmentState.STA);
th_0.Start();
6、接收到客户端数据查询的事件(供界面信息显示非必须)
/// <summary>
/// 接收事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void _modbusSlave_ModbusSlaveRequestReceived(object sender, ModbusSlaveRequestEventArgs e)
{
BeginInvoke(new MethodInvoker(() =>
{
label1.Text = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss:fff") + ":" + e.Message.ToString();
}));
}
7、服务器的数据区赋值(此处仅测试,实际生产环境根据需求做赋值)
Thread th_1 = new Thread(() =>
{
SetData(); //数据区数据赋值
})
{
IsBackground = true,
};
th_1.SetApartmentState(ApartmentState.STA);
th_1.Start();
/// <summary>
/// 设置数据
/// </summary>
private void SetData()
{
while (true)
{
Data.InputRegisters[1] = (ushort)DateTime.Now.Year; //年
Data.InputRegisters[2] = (ushort)DateTime.Now.Month; //月
Data.InputRegisters[3] = (ushort)DateTime.Now.Day; //日
Data.InputRegisters[4] = (ushort)DateTime.Now.Hour; //时
Data.InputRegisters[5] = (ushort)DateTime.Now.Minute; //分
Data.InputRegisters[6] = (ushort)DateTime.Now.Second; //秒
Data.InputRegisters[7] = (ushort)DateTime.Now.Millisecond; //毫秒
Random ran = new Random();
Data.InputRegisters[8] = (ushort)ran.Next(0, 32767); //产生的随机数
///界面显示
BeginInvoke(new MethodInvoker(() =>
{
richTextBox1.Clear();
richTextBox1.AppendText($@"30001={Data.InputRegisters[1]}" + "\r\n");
richTextBox1.AppendText($@"30002={Data.InputRegisters[2]}" + "\r\n");
richTextBox1.AppendText($@"30003={Data.InputRegisters[3]}" + "\r\n");
richTextBox1.AppendText($@"30004={Data.InputRegisters[4]}" + "\r\n");
richTextBox1.AppendText($@"30005={Data.InputRegisters[5]}" + "\r\n");
richTextBox1.AppendText($@"30006={Data.InputRegisters[6]}" + "\r\n");
richTextBox1.AppendText($@"30007={Data.InputRegisters[7]}" + "\r\n");
richTextBox1.AppendText($@"30008={Data.InputRegisters[8]}" + "\r\n");
}));
Thread.Sleep(1000);
}
8、运行测试: