| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 | 
							- package modbus
 
- import (
 
- 	"bytes"
 
- 	"encoding/binary"
 
- 	"fmt"
 
- )
 
- const (
 
- 	FuncCode3  uint8 = 0x03 // FuncCode3 功能码 3 读取多个连续保持寄存器
 
- 	FuncCode16 uint8 = 0x10 // FuncCode16 功能码 16 写入多个连续保持寄存器
 
- )
 
- const (
 
- 	MinTCPReqSize  = 6
 
- 	MinTCPRespSize = 9
 
- )
 
- type TCPRequest struct {
 
- 	TransactionID uint16 // TransactionID 事务标识符
 
- 	ProtocolID    uint16 // ProtocolID 协议标识符, 通常情况下为 0x0000
 
- 	length        uint16 // length 数据长度, 不包含 TransactionID 和 ProtocolID
 
- 	UnitID        uint8  // UnitID 单元标识符, 即起设备 ID
 
- 	FunctionCode  uint8  // FunctionCode 功能码
 
- 	StartNo       uint16 // StartNo 起始地址
 
- 	RegisterLen   uint16 // RegisterLen 根据 StartNo 的连续读取或写入的寄存器数量
 
- 	Data          []byte // Data 需要写入的数据
 
- }
 
- func (m *TCPRequest) Pack() []byte {
 
- 	b := make([]byte, 12+len(m.Data))
 
- 	binary.BigEndian.PutUint16(b[0:], m.TransactionID)
 
- 	binary.BigEndian.PutUint16(b[2:], m.ProtocolID)
 
- 	binary.BigEndian.PutUint16(b[4:], m.length)
 
- 	m.length = MinTCPReqSize + uint16(len(m.Data))
 
- 	b[5] = m.UnitID
 
- 	b[6] = m.FunctionCode
 
- 	binary.BigEndian.PutUint16(b[7:], m.StartNo)
 
- 	binary.BigEndian.PutUint16(b[9:], m.RegisterLen)
 
- 	if m.length > MinTCPReqSize {
 
- 		copy(b[12:], m.Data)
 
- 	}
 
- 	return b
 
- }
 
- type TCPResponse struct {
 
- 	TransactionID uint16 // TransactionID 事务标识符
 
- 	ProtocolID    uint16 // ProtocolID 协议标识符, 通常情况下为 0x0000
 
- 	Length        uint16 // Length 数据长度, 不包含 TransactionID 和 ProtocolID
 
- 	UnitID        uint8  // UnitID 单元标识符, 即起设备 ID
 
- 	FunctionCode  uint8  // FunctionCode 功能码
 
- 	DataLength    uint8  // DataLength Data 的数据长度
 
- 	Data          []byte // Data 返回的数据
 
- }
 
- func (m *TCPResponse) UnpackWithRequest(b []byte, r *TCPRequest) error {
 
- 	if err := m.Unpack(b); err != nil {
 
- 		return err
 
- 	}
 
- 	if r.TransactionID != m.TransactionID {
 
- 		return fmt.Errorf("TransactionID: request is not equal to that of the response")
 
- 	}
 
- 	if r.ProtocolID != m.ProtocolID {
 
- 		return fmt.Errorf("ProtocolID: request is not equal to that of the response")
 
- 	}
 
- 	if r.FunctionCode != m.FunctionCode {
 
- 		return fmt.Errorf("FunctionCode: request is not equal to that of the response")
 
- 	}
 
- 	return nil
 
- }
 
- func (m *TCPResponse) Unpack(b []byte) error {
 
- 	if len(b) < MinTCPRespSize {
 
- 		return fmt.Errorf("data too short: %d", len(b))
 
- 	}
 
- 	buf := bytes.NewReader(b)
 
- 	if err := binary.Read(buf, binary.BigEndian, &m.TransactionID); err != nil {
 
- 		return err
 
- 	}
 
- 	if err := binary.Read(buf, binary.BigEndian, &m.ProtocolID); err != nil {
 
- 		return err
 
- 	}
 
- 	if err := binary.Read(buf, binary.BigEndian, &m.Length); err != nil {
 
- 		return err
 
- 	}
 
- 	// UnitID 使用小端模式读取
 
- 	if err := binary.Read(buf, binary.LittleEndian, &m.UnitID); err != nil {
 
- 		return err
 
- 	}
 
- 	// FunctionCode 使用小端模式读取
 
- 	if err := binary.Read(buf, binary.LittleEndian, &m.FunctionCode); err != nil {
 
- 		return err
 
- 	}
 
- 	if err := binary.Read(buf, binary.BigEndian, &m.DataLength); err != nil {
 
- 		return err
 
- 	}
 
- 	m.Data = make([]byte, buf.Len())
 
- 	_, err := buf.Read(m.Data)
 
- 	return err
 
- }
 
 
  |