1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLY.ModbusModule
{
public static class COMMON
{
/// <summary>
/// 把2个byte 转为 uint16
/// </summary>
/// <param name="value"></param>
/// <param name="startIndex"></param>
/// <returns></returns>
public static UInt16 ToUInt16_Big_endian(byte[] value, int startIndex)
{
return (UInt16)((value[startIndex] << 8) | value[startIndex+1]);
}
/// <summary>
/// 把 uint16 转为2个byte
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static byte[] GetBytes_Big_endian(this UInt16 value)
{
byte[] b = new byte[2];
b[0] = (byte)(value >> 8);
b[1] = (byte)value;
return b;
}
}
public class Pack_Proto
{
public UInt16 tranid;
public byte unitid;
public byte func;
public byte[] buf = null;
//格式——————————————
//MBAP
//域 长度 描述
//事务标识符 2byte MODBUS请求/响应的识别码
//协议标识符 2byte 0=MODBUS协议
//——长度— 2byte 以下字节的数量
//单元标识符 1byte 串行链路或其它总线过来的识别码
//PDU
//功能码—— 1byte
//数据 nbyte
public byte[] ToBytes()
{
List<byte> buf = new List<byte>();
buf.AddRange(tranid.GetBytes_Big_endian());
buf.AddRange(((UInt16)0).GetBytes_Big_endian());
UInt16 len = (UInt16)(1 + 1 + this.buf.Count());
buf.AddRange(len.GetBytes_Big_endian());
buf.Add(unitid);
buf.Add(func);
if (this.buf != null)
buf.AddRange(this.buf);
return buf.ToArray();
}
public bool TryParse(byte[] value, int startIndex, out int rlen)
{
//格式——————————————
//MBAP
//域 长度 描述
//事务标识符 2byte MODBUS请求/响应的识别码
//协议标识符 2byte 0=MODBUS协议
//——长度— 2byte 以下字节的数量
//单元标识符 1byte 串行链路或其它总线过来的识别码
//PDU
//功能码—— 1byte
//数据 nbyte
rlen = 0;
int cnt = 7 + 1;
if (value.Count() < cnt)
return false;
int index = startIndex;
tranid = COMMON.ToUInt16_Big_endian(value, index);
index += 2;
UInt16 protoid = COMMON.ToUInt16_Big_endian(value, index);
index += 2;
int len = COMMON.ToUInt16_Big_endian(value, index);
index += 2;
cnt += len - 2;
if (value.Count() < cnt)
return false;
unitid = value[index];
index++;
func = value[index];
index++;
len -= 2;
if (len > 0)
{
buf = new byte[len];
Array.Copy(value, index, buf, 0, len);
}
rlen = cnt;
return true;
}
}
}