package adapter import ( "encoding/binary" "errors" "io" ) // 协议常量. const ( // MessageTypeData 表示数据消息. MessageTypeData byte = 0x01 // MessageTypeAck 表示 ACK 确认. MessageTypeAck byte = 0x02 // MessageTypeNack 表示 NACK 否定确认. MessageTypeNack byte = 0x03 // 协议限制. maxTopicLength = 65535 maxUUIDLength = 255 maxPayloadSize = 1 << 30 topicLengthSize = 2 uuidLengthSize = 1 payloadLengthSize = 4 ) // 预定义错误. var ( ErrNilMessage = errors.New("message is nil") ErrTopicTooLong = errors.New("topic too long") ErrUUIDTooLong = errors.New("uuid too long") ErrPayloadTooLarge = errors.New("payload too large") ) // TCPMessage 表示 TCP 传输的消息. type TCPMessage struct { Type byte // 消息类型 Topic string // 主题 UUID string // 消息 UUID Payload []byte // 消息内容 } // EncodeTCPMessage 将消息编码为字节数组. // 格式: [消息类型 1字节][Topic长度 2字节][Topic][UUID长度 1字节][UUID][Payload长度 4字节][Payload]. func EncodeTCPMessage(msg *TCPMessage) ([]byte, error) { if msg == nil { return nil, ErrNilMessage } topicLen := len(msg.Topic) if topicLen > maxTopicLength { return nil, ErrTopicTooLong } uuidLen := len(msg.UUID) if uuidLen > maxUUIDLength { return nil, ErrUUIDTooLong } payloadLen := len(msg.Payload) if payloadLen > maxPayloadSize { return nil, ErrPayloadTooLarge } // 计算总长度 totalLen := 1 + topicLengthSize + topicLen + uuidLengthSize + uuidLen + payloadLengthSize + payloadLen buf := make([]byte, totalLen) offset := 0 // 写入消息类型 buf[offset] = msg.Type offset++ // 写入 Topic 长度和内容 binary.BigEndian.PutUint16(buf[offset:], uint16(topicLen)) offset += topicLengthSize copy(buf[offset:], []byte(msg.Topic)) offset += topicLen // 写入 UUID 长度和内容 buf[offset] = byte(uuidLen) offset++ copy(buf[offset:], []byte(msg.UUID)) offset += uuidLen // 写入 Payload 长度和内容 binary.BigEndian.PutUint32(buf[offset:], uint32(payloadLen)) offset += payloadLengthSize copy(buf[offset:], msg.Payload) return buf, nil } // DecodeTCPMessage 从字节数组解码消息. func DecodeTCPMessage(reader io.Reader) (*TCPMessage, error) { msg := &TCPMessage{} // 读取消息类型 msgTypeBuf := make([]byte, 1) if _, err := io.ReadFull(reader, msgTypeBuf); err != nil { return nil, err } msg.Type = msgTypeBuf[0] // 读取 Topic 长度 topicLenBuf := make([]byte, topicLengthSize) if _, err := io.ReadFull(reader, topicLenBuf); err != nil { return nil, err } topicLen := binary.BigEndian.Uint16(topicLenBuf) // 读取 Topic topicBuf := make([]byte, topicLen) if _, err := io.ReadFull(reader, topicBuf); err != nil { return nil, err } msg.Topic = string(topicBuf) // 读取 UUID 长度 uuidLenBuf := make([]byte, 1) if _, err := io.ReadFull(reader, uuidLenBuf); err != nil { return nil, err } uuidLen := uuidLenBuf[0] // 读取 UUID uuidBuf := make([]byte, uuidLen) if _, err := io.ReadFull(reader, uuidBuf); err != nil { return nil, err } msg.UUID = string(uuidBuf) // 读取 Payload 长度 payloadLenBuf := make([]byte, payloadLengthSize) if _, err := io.ReadFull(reader, payloadLenBuf); err != nil { return nil, err } payloadLen := binary.BigEndian.Uint32(payloadLenBuf) // 读取 Payload payloadBuf := make([]byte, payloadLen) if _, err := io.ReadFull(reader, payloadBuf); err != nil { return nil, err } msg.Payload = payloadBuf return msg, nil }