package components import ( "bytes" "encoding/binary" "fmt" "pro2d/common" ) type PBHead struct { Length uint32 Cmd uint32 ErrCode int32 PreField uint32 } func (h *PBHead) GetDataLen() uint32 { return h.Length } func (h *PBHead) GetMsgID() uint32 { return h.Cmd } func (h *PBHead) GetErrCode() int32 { return h.ErrCode } func (h *PBHead) GetPreserve() uint32 { return h.PreField } type PBMessage struct { IMessage Head IHead Body []byte conn IConnection } func (m *PBMessage) GetHeader() IHead { return m.Head } func (m *PBMessage) SetHeader(header IHead) { m.Head = header } func (m *PBMessage) GetData() []byte { return m.Body } func (m *PBMessage) SetData(b []byte) { m.Body = b } func (m *PBMessage) SetSession(connection IConnection) { m.conn = connection } func (m *PBMessage) GetSession() IConnection { return m.conn } type PBSplitter struct {} func NewPBSplitter() *PBSplitter { return &PBSplitter{} } func (m *PBSplitter) GetHeadLen() uint32 { return uint32(binary.Size(PBHead{})) } func (m *PBSplitter) UnPack(data []byte) (IMessage,error) { h := &PBHead{} err := binary.Read(bytes.NewReader(data), binary.BigEndian, h) if err != nil { return nil, err } return &PBMessage{ Head: h, Body: data[m.GetHeadLen():], },nil } func (m *PBSplitter) ParseMsg (data []byte, atEOF bool) (advance int, token []byte, err error) { // 表示我们已经扫描到结尾了 if atEOF && len(data) == 0 { return 0, nil, nil } if !atEOF && len(data) >= int(m.GetHeadLen()) { //4字节数据包长度 4字节指令 length := int32(0) binary.Read(bytes.NewReader(data[0:4]), binary.BigEndian, &length) if length <= 0 { return 0, nil, fmt.Errorf("length is 0") } if length > common.MaxPacketLength { return 0, nil, fmt.Errorf("length exceeds maximum length") } if int(length) <= len(data) { return int(length) , data[:int(length)], nil } return 0 , nil, nil } if atEOF { return len(data), data, nil } return 0, nil, nil } func (m *PBSplitter) Pack(cmd uint32, data []byte, errcode int32, preserve uint32) ([]byte, error) { buf := &bytes.Buffer{} h := &PBHead{ Length: m.GetHeadLen()+ uint32(len(data)), Cmd: cmd, ErrCode: errcode, PreField: preserve, } err := binary.Write(buf, binary.BigEndian, h) if err != nil { return nil, err } err = binary.Write(buf, binary.BigEndian, data) if err != nil { return nil, err } return buf.Bytes(), nil }