C#实现MODBUS TCP 通信 第二章 (程序内实现)

上一章,我们对MODBUS 的报文已经有初步了解,本章就在程序内来具体实现,我先建立了一个MODBUS 方法类,类中包含有常用的读写方法,以及数据处理方法,由于我是用在实际生产中,所以对寄存器的值有限制,只能是正数,所以还有数据转换方法,可以作为参考,类的具体代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace ModbusTCPDemo
{
public class ModbusTCP
{
private Socket socket = null;
public bool Connect(string ip, int port)
{
//实例化Socket
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
socket.Connect(IPAddress.Parse(ip), port);
return true;
}
catch (Exception)
{
return false;
}
}
    public void DisConnect()
    {
        if (socket != null)
        {
            socket.Close();
        }
    }
    //读取寄存器
    public ushort[] ReadKeeepReg(ushort start, ushort length)
    {
        //拼接
        List<byte> SendCommand = new List<byte>();
        //事物处理标识符
        SendCommand.AddRange(new byte[] { 0x00, 0x00 });
        //协议标识符
        SendCommand.AddRange(new byte[] { 0x00, 0x00 });
        //长度
        SendCommand.AddRange(new byte[] { 0x00, 0x06 });
        //单元标识符
        SendCommand.Add(0x01);
        //功能码
        SendCommand.Add(0x03);
        //起始地址
        SendCommand.Add((byte)(start / 256));
        SendCommand.Add((byte)(start % 256));
        //结束地址-长度
        SendCommand.Add((byte)(length / 256));
        SendCommand.Add((byte)(length % 256));
        //发送
        socket.Send(SendCommand.ToArray());
        //接收
        byte[] buffer = new byte[512];
        int count = socket.Receive(buffer, SocketFlags.None);
        //验证-截取
        byte[] result = new byte[count];
        Array.Copy(buffer, 0, result, 0, count);
        if (count == 9 + 2 * length)
        {
            if (result[7] == 0x03)
            {
                //解析
                ushort[] data = new ushort[length];
                for (int i = 0; i < data.Length; i++)
                {
                    data[i] = BitConverter.ToUInt16(new byte[] { result[9 + 2 * i + 1], result[9 + 2 * i] },0);

                }
                return data;
            }
            return null;
        }
        return null;
    }

    //写入单个寄存器
    public List<byte> WriteInputRge(short start, short writedata)
    {
        //拼接
        List<byte> SendCommand = new List<byte>();
        //事物处理标识符
        SendCommand.AddRange(new byte[] { 0x00, 0x00 });
        //协议标识符
        SendCommand.AddRange(new byte[] { 0x00, 0x00 });
        //长度
        SendCommand.AddRange(new byte[] { 0x00, 0x06 });
        //单元标识符
        SendCommand.Add(0x01);
        //功能码
        SendCommand.Add(0x06);
        //寄存器地址
        SendCommand.Add((byte)(start / 256));
        SendCommand.Add((byte)(start % 256));
        //具体数据
        SendCommand.Add((byte)(writedata / 256));
        SendCommand.Add((byte)(writedata % 256));
        //发送
        socket.Send(SendCommand.ToArray());
        //接收
        byte[] buffer = new byte[512];
        int count = socket.Receive(buffer, SocketFlags.None);
        //验证-截取
        byte[] result = new byte[count];
        Array.Copy(buffer, 0, result, 0, count);
        List<byte> ReceiveCommand = result.ToList();
        if (ReceiveCommand[0] == SendCommand[0])
        {
            return ReceiveCommand;
        }
        return null;

    }

    //写入多个寄存器
    public List<byte> BatchWriteInputRge(short start, short length,short[] data)
    {
        //拼接
        List<byte> SendCommand = new List<byte>();
        //事物处理标识符
        SendCommand.AddRange(new byte[] { 0x00, 0x00 });
        //协议标识符
        SendCommand.AddRange(new byte[] { 0x00, 0x00 });
        //长度
        SendCommand.Add((byte)((9 + (length - 1) * 2) / 256));
        SendCommand.Add((byte)((9 + (length - 1) * 2) % 256));
        //单元标识符
        SendCommand.Add(0x01);
        //功能码
        SendCommand.Add(0x10);
        //寄存器地址
        SendCommand.Add((byte)(start / 256));
        SendCommand.Add((byte)(start % 256));
        //寄存器个数
        SendCommand.Add((byte)(length / 256));
        SendCommand.Add((byte)(length % 256));
        //写字节个数
        SendCommand.Add((byte)(data.Length*2));
        for (int i = 0; i < data.Length; i++)
        {
            SendCommand.Add((byte)(data[i] / 256));
            SendCommand.Add((byte)(data[i] % 256));
        }

        //发送
        socket.Send(SendCommand.ToArray());
        //接收
        byte[] buffer = new byte[512];
        int count = socket.Receive(buffer, SocketFlags.None);
        //验证-截取
        byte[] result = new byte[count];
        Array.Copy(buffer, 0, result, 0, count);
        List<byte> ReceiveCommand = result.ToList();
        if (ReceiveCommand[0] == SendCommand[0])
        {
            return ReceiveCommand;
        }
        return null;

        //  00 00   00 00   00 0B   01   10   00 00  00 02  04  00 99  11 55 
    }

    //数据拆分方法,将一个32位int 转换成4个8位int
    public int[] Int32BitTo8Bit(int i)
    {
        int[] ints = new int[4];
        if (i > 0)
        {
            int n1 = i & 0xffff;
            int n2 = i >> 16;
            ints[0] = n1 & 0xff;
            ints[1] = n1 >> 8;
            ints[2] = n2 & 0xff;
            ints[3] = n2 >> 8;

            int ii = (((ints[3] << 8) + ints[2]) << 16) + ((ints[1] << 8) + ints[0]);

            return ints;
        }
        return null;
    }

}

实现步骤:
1.建立连接
2.调用方法

ModbusTCP modbusTCP = new ModbusTCP(); //实例化ModbusTCP 类
if (modbusTCP.Connect("127.0.0.1", 502))//调用连接方法
{
int[] data_int = modbusTCP.Int32BitTo8Bit(Convert.ToInt32(zcl));
short[] data_short = new short[data_int.Length];
for (int i = 0; i < data_int.Length; i++)
{
data_short[i] = (short)data_int[i];
}
                System.Collections.Generic.List<byte> val = modbusTCP.BatchWriteInputRge(0, (short)data_short.Length, data_short);
                if (val != null)
                {
                    string s="";
                    for (int i = 0; i < val.Count; i++)
                    {
                        s +=" " + val[i].ToString();
                    }
                    Console.WriteLine("写入成功返回:"+s);
                }
                else
                {
                    Console.WriteLine("写入失败!");
                }
图片[1]-C#实现MODBUS TCP 通信 第二章 (程序内实现)-民间安全 - 白帽子黑客在线学习安全交流平台
© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片