C# modbus Tcp协议数据抓取和使用
基于Modbus tcp 协议的数据抓取,并解析,源码使用C#开发
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Net;
- using System.Net.Sockets;
- using System.Text;
- namespace modbus
- {
- class Program
- {
- #region 字节转换为16进制字符
- /// <summary>
- /// 字节转换为16进制字符
- /// </summary>
- /// <param name="data"></param>
- /// <returns></returns>jiang
- static string ByteToHexString(byte[] data)
- {
- string strTemp = "";
- for (int i = 2; i < data.Length; i++)
- {
- string a = Convert.ToString(data[i], 16).PadLeft(2, '0');
- strTemp = strTemp + a;
- }
- return strTemp.Substring(0, 100);
- }
- #endregion
- #region 16进制字符转换为字节
- /// <summary>
- /// 16进制字符转换为字节
- /// </summary>
- /// <param name="hs"></param>
- /// <returns></returns>
- static byte[] HexString(string hs)
- {
- hs = hs.Replace(" ", "");
- string strTemp = "";
- byte[] b = new byte[hs.Length / 2];
- for (int i = 0; i < hs.Length / 2; i++)
- {
- strTemp = hs.Substring(i * 2, 2);
- b[i] = Convert.ToByte(strTemp, 16);
- }
- return b;
- }
- #endregion
- #region 发送、接收报文并返回报文
- /// <summary>
- /// 發送或接受風機指令
- /// </summary>
- /// <param name="sendCodeMeg">指令</param>
- /// <param name="IpAddress">IP地址</param>
- /// <param name="panelIP">面板IP</param>
- /// <returns></returns>
- static string SendPack(string sendCodeMeg, string IpAddress, int port)
- {
- IPAddress ip = IPAddress.Parse(IpAddress);
- Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- try
- {
- Console.WriteLine("開始發送數據。。。");
- clientSocket.Connect(new IPEndPoint(ip, port)); //配置服务器ip和端口
- //TcpClient tcpClient = new TcpClient();
- Console.WriteLine("服务器连接成功");
- }
- catch
- {
- Console.WriteLine("连接服务器失败\n");
- return null;
- }
- try
- {
- string sendMessage = sendCodeMeg; // "6B 00 00 00 00 06 02 06 05 10 00 01"; //发送到服务端的内容
- var sendData = HexString(sendMessage);
- string recvStr = null;
- int bytes;
- try
- {
- Console.WriteLine("发送报文:{0}", sendMessage);
- clientSocket.Send(sendData);//向服务器发送数据
- byte[] recvBytes = new byte[1024];
- //连接时长500ms
- clientSocket.ReceiveTimeout = 5000;
- bytes = clientSocket.Receive(recvBytes, recvBytes.Length, 0); //服务端接受返回信息
- recvStr += ByteToHexString(recvBytes);
- }
- catch (Exception ex)
- {
- Console.WriteLine("出现错误!\n{0}\n\n", ex);
- recvStr = null;
- }
- if (recvStr != null)
- {
- Console.WriteLine("获取成功!\n 获得数据:{0}\n\n", recvStr);
- }
- clientSocket.Close();//关闭连接释放资源
- //Console.ReadLine();
- return recvStr;
- }
- catch
- {
- Console.WriteLine("出现错误!\n");
- return null;
- }
- }
- #endregion
- //主函数
- static void Main(string[] args)
- {
- Console.WriteLine("开始!");
- string IP = "10.139.49.61";
- int port = 502;
- int fnu = 4;
- string a = fnu.ToString("x2");
- string sendCodeMeg1 = "02 00 00 00 00 06 01 03 01 10 00 02";
- string sendCodeMeg2 = "03 00 00 00 00 06 01 03 01 0A 00 02";
- string data1 = null;
- string data2 = null;
- for (int num = 0; num < 5; num++)
- {
- Console.WriteLine("第{0}次调用Get_Fan函数!\n", num + 1);
- data1 = SendPack(sendCodeMeg1, IP, port);
- if (data1 != null)
- {
- break;
- }
- }
- for (int num = 0; num < 5; num++)
- {
- Console.WriteLine("第{0}次调用Get_Fan函数!\n", num + 1);
- data2 = SendPack(sendCodeMeg2, IP, port);
- if (data2 != null)
- {
- break;
- }
- }
- Console.WriteLine("结束");
- Console.ReadKey();
- }
- }
- }
C# modbus tcp读写数据
1.引用-添加引用-HslCommunication.dll

2.ModBus组件所有的功能类都在 HslCommunication.ModBus命名空间,所以再使用之前先添加
- using HslCommunication.ModBus;
- using HslCommunication;
3.在使用读写功能之前必须先进行实例化:
- private ModbusTcpNet busTcpClient = new ModbusTcpNet("192.168.3.45", 502, 0x01); // 站号1
上面的实例化指定了服务器的IP地址,端口号(一般都是502),以及自己的站号,允许设置为0-255,后面的两个参数有默认值,在实例化的时候可以省略。
- private ModbusTcpNet busTcpClient = new ModbusTcpNet("192.168.3.45"); // 端口号502,站号1
4.

- 模拟器模拟的是西门子PLC 有四种类型
- 地址以0开头的是可读可写线圈
- 地址以1开头的是只读线圈
- 地址以4开头的是可读可写寄存器(string/float/int/ushort/short等都可以放在这里面)
- 地址以3开头的是只读寄存器
- 我们读取的时候只看后四位0001,就是1,但是库里面是从0开始读的,所以对应的就要减一
5.读取寄存器的一个值
- private void button1_Click(object sender, EventArgs e)
- {
- bool coil100 = busTcpClient.ReadCoil("0").Content; // 读取线圈1的通断
- int int100 = busTcpClient.ReadInt32("0").Content; // 读取寄存器1-2的int值
- float float100 = busTcpClient.ReadFloat("0").Content; // 读取寄存器1-2的float值
- double double100 = busTcpClient.ReadDouble("0").Content; // 读取寄存器1-3的double值
- }
6.读取寄存器的一组值(一组线圈)(一组float值)
- private void button3_Click(object sender, EventArgs e)
- {
- //读取地址为0,长度为3的线圈数量
- OperateResult<bool[]> read = busTcpClient.ReadCoil("0", 3);
- if (read.IsSuccess)
- {
- for (int i = 0; i < read.Content.Length; i++)
- {
- Console.WriteLine(read.Content[i]);
- }
- }
- else
- {
- MessageBox.Show(read.ToMessageShowString());
- }
-
- //读取(一组)寄存器数据
- OperateResult<float[]> result = busTcpClient.ReadFloat("0", 4);
- if (result.IsSuccess)
- {
- //Console.WriteLine(result.Content[0]);
- //Console.WriteLine(result.Content[1]);
- //Console.WriteLine(result.Content[2]);
- for (int i = 0; i < result.Content.Length; i++)
- {
- Console.WriteLine(result.Content[i]);
- }
- }
- else
- {
- MessageBox.Show(result.ToMessageShowString());
- }
- }
7.写入一个(线圈)(寄存器)
- private void button2_Click(object sender, EventArgs e)
- {
- busTcpClient.WriteCoil("0", true);// 写入线圈1为通
- busTcpClient.Write("0", 123.456);// 写入寄存器1-2为123.456
- }
8.批量写入一组(线圈)(寄存器)
- private void button9_Click(object sender, EventArgs e)
- {
- //写入一组线圈
- bool[] value = new bool[] { true, true, false, true, false };
- busTcpClient.WriteCoil("0", value);
- }
- private void button10_Click(object sender, EventArgs e)
- {
- //写入一组寄存器
- float[] value = new float[] {1.1F, 1.2F, 1.3F, 1.4F, 1.5F };
- busTcpClient.Write("0", value);
- }
-
以上为个人经验,希望能给大家一个参考,也希望大家多多支持w3xue。