• C#Modbus服务器搭建


    1 private TcpListener tcpListener;
    1 static bool isEnable = false;     //是否加载成功
    2         static bool isSend = false;   //是否发送成功
    3         static bool isRead = false;   //是否读取成功

    启动服务

     1 public void StartServer()
     2         {
     3             if (tcpListener == null)
     4             {
     5                 tcpListener = new TcpListener(IPAddress.Parse("0.0.0.0"), 9003);
     6                 tcpListener.Start();
     7                 Console.WriteLine("启动服务:9003");
     8                 while (true)
     9                 {
    10                     TcpClient tcpClient = tcpListener.AcceptTcpClient();
    11                     System.Threading.Tasks.Task.Factory.StartNew(() => DoListener(tcpClient));
    12                     Thread.Sleep(100);
    13                 }
    14             }
    15         }

    打开监听

     1 private void DoListener(TcpClient tcpClient)
     2         {
     3             tcpClient.SendTimeout = 30000;
     4             tcpClient.ReceiveTimeout = 30000;
     5             //編輯地址
     6             ushort ad = 14288;
     7             try
     8             {
     9                 
    10                 while (true)
    11                 {
    12 
    13                     if (!isEnable)
    14                     {
    15                         Console.WriteLine("重置状态中...");
    16                         InitState(tcpClient.Client, 57357, "00000001");
    17                         Thread.Sleep(50);
    18                         continue;
    19                     }
    20                     if (!isSend)
    21                     {
    22                         Console.WriteLine("写...");
    23                         List<byte> data = new List<byte>(255);
    24                         data.Add(Convert.ToByte(24));
    25                         SendInfo(tcpClient.Client, ad, 85, "00000001", 16, data.ToArray());
    26                         Thread.Sleep(50);
    27                         continue;
    28                     }
    29                     if (!isRead)
    30                     {
    31                         Console.WriteLine("读...");
    32                         ReadInfo(tcpClient.Client, ad, 85, DataType.Ushort);
    33                         Thread.Sleep(50);
    34                         continue;
    35                     }  
    36                 }
    37             }
    38             catch (Exception ex)
    39             {
    40                 Console.WriteLine(ex.ToString());
    41             }
    42         }

    停止监听

    1 public void DisposeServer()
    2         {
    3             if (tcpListener != null)
    4             {
    5                 tcpListener.Stop();
    6                 tcpListener = null;
    7             }
    8         }

    读取数据

     1 public static object[] ReadInfo(Socket socket, ushort add, short len, DataType type)
     2         {
     3             //构建发送报文
     4             byte[] data = BuidReadMessage(add, len);
     5             socket.Send(data, data.Length, SocketFlags.None);
     6             int size = len * 2 + 7;
     7             byte[] rdata = new byte[size];
     8             socket.Receive(rdata, size, SocketFlags.None);
     9             Console.WriteLine("" + add + "获取数据(" + len + "):" + StringUtils.ByteToHex(rdata));
    10             //判断是否成功。
    11             if ((rdata[0] == data[0] && rdata[1] == data[1]))
    12             {
    13                 isRead = true;
    14                 List<object> listData = new List<object>();
    15                 for (int i = 3; i < rdata[2] + 3;)
    16                 {
    17                     //listData.Add(BitConverter.ToUInt16(rdata, i));
    18                     //i += 2;
    19                     if (type == DataType.Ushort)
    20                     {
    21                         listData.Add(BitConverter.ToUInt16(new byte[] { rdata[i + 1], rdata[i] }, 0));
    22                         i += 2;
    23                     }
    24                     else if (type == DataType.Int)
    25                     {
    26                         listData.Add(BitConverter.ToInt32(new byte[] { rdata[i + 1], rdata[i], rdata[i + 3], rdata[i + 2] }, 0));
    27                         i += 4;
    28                     }
    29                     else if (type == DataType.Binary)
    30                     {
    31                         string strBase1 = Convert.ToString(rdata[i], 2).PadLeft(8, '0');
    32                         string strBase2 = Convert.ToString(rdata[i + 1], 2).PadLeft(8, '0');
    33                         listData.Add(ReverseString(strBase2) + ReverseString(strBase1));
    34                         i += 2;
    35                     }
    36                     else if (type == DataType.Bit)
    37                     {
    38                         string strBase1 = Convert.ToString(rdata[i], 1);
    39                         listData.Add(rdata[i]);
    40                         i += 1;
    41                     }
    42                     else
    43                     {
    44                         listData.Add(System.Text.Encoding.UTF8.GetString(rdata, 3, rdata[2]));
    45                         i += rdata[2];
    46                     }
    47                 }
    48                 return listData.ToArray();
    49             }
    50             return new object[0];
    51         }

    写入

     1  public static void SendInfo(Socket socket, ushort add, short len, string type, short fCode, byte[] toValues)
     2         {
     3             byte[] data= BuildSendMessage(add, toValues, len,type,fCode);
     4             socket.Send(data, data.Length, SocketFlags.None);
     5             byte[] rdata = new byte[10];
     6             socket.Receive(rdata, 10, SocketFlags.None);
     7             //判断是否成功
     8             if (data[0] == rdata[0] && data[1] == rdata[1])
     9                 isSend = true;
    10         }

    构建读取报文

     1 public static byte[] BuidReadMessage(ushort add,short len)
     2         {
     3             byte[] addr = StringUtils.DataConvertToBytes(add);
     4             byte[] length = StringUtils.DataConvertToBytes(len);
     5             List<byte> data = new List<byte>(255);
     6 
     7             data.Add(Convert.ToByte(1));                                        
     8             data.Add(Convert.ToByte(3));     //功能码                                      
     9             data.AddRange(addr);                   
    10             data.AddRange(length);                        
    11             byte[] dataBuff = CRC.ToModbusCRC16Byte(data.ToArray(), true);
    12             data.AddRange(dataBuff);                          
    13             return data.ToArray();
    14         }

    构建发送报文

     1  public static byte[] BuildSendMessage(ushort add, byte[] toValues, short len,string type, short fCode)
     2         {
     3             short id = 1;
     4             List<byte> data = new List<byte>(255);
     5             data.Add(Convert.ToByte(id));                                             
     6             data.Add(Convert.ToByte(fCode));                                              
     7             data.AddRange(StringUtils.DataConvertToBytes(add));                          
     8             data.AddRange(StringUtils.DataConvertToBytes(len));                         
     9             data.Add(Convert.ToByte(Math.Ceiling(Convert.ToDecimal(len) / 8)));
    10             byte[] b = new byte[data.Count+ toValues.Length];
    11             Array.Copy(data.ToArray(), 0, b, 0, data.Count);
    12             Array.Copy(toValues, 0, b, data.Count, toValues.Length);
    13             byte[] dataBuff = new byte[2];
    14             dataBuff = CRC.ToModbusCRC16Byte(b, true);
    15             data.AddRange(toValues);   
    16             data.AddRange(dataBuff);                    
    17             return data.ToArray();
    18         }

    读取到的数值转换

    1  private static string ReverseString(string value)
    2         {
    3             char[] ch = value.ToArray();//把文本框你的内容转换为char类型数组
    4             Array.Reverse(ch, 0, value.Length);//使用Array类的Reverse方法颠倒数据
    5             return new StringBuilder().Append(ch).ToString();//获取指定数组的字符串显示到控件
    6         }

    重置状态

     1 public static void InitState(Socket socket,ushort add,string type)
     2         {
     3             try
     4             {
     5                 byte[] data = BuildSendMessage1(add, type, 1);
     6                 socket.Send(data, data.Length, SocketFlags.None);
     7                 byte[] rdata = new byte[10];
     8                 socket.Receive(rdata, rdata.Length, SocketFlags.None);
     9                 //判断是否成功
    10                 if (rdata[0] == data[0] && rdata[1] == data[1])
    11                     isEnable = true;
    12             }
    13             catch (Exception ex)
    14             {
    15                 Console.WriteLine(ex.ToString());
    16             }
    17         }

    ModBus和PLC进行交互流程是:通过socket 发送报文,然后接收到返回的结果。

    报文格式:

    读  路由 功能码 地址 长度  校验码

    写  路由 功能码 地址 长度 字节数量 写入的数据 校验码

    是读是写依靠功能码去区别。线圈和寄存器的区别,线圈存储的是 0/1,只能存储一个Bool;寄存器可以存储数据

    常用的功能码

    1  读取线圈

    3  读取寄存器

    5  写单个寄存器

    15  写线圈

    16  写多个寄存器

  • 相关阅读:
    java项目路径获取
    String.getBytes()和new String()(string与byte[]的转换)
    Android生成一维码
    Android PullToRefresh (GridView 下拉刷新上拉加载)
    Android PullToRefresh (ListView GridView 下拉刷新) 使用详解
    Android 二维码扫描框 加四个角及中间横线自动下滑
    android 百度地图定位开发2
    android 百度地图定位开发1
    广播发送者&广播接收者介绍
    电脑配置 eclipse 环境变量
  • 原文地址:https://www.cnblogs.com/ThisYbc/p/15234021.html
Copyright © 2020-2023  润新知