package simple import ( "bytes" "encoding/binary" "io" "net" cerr "github.com/mhaya/error" ) var ( NoneMessage = Message{} // none message headLength = 8 // ID uint32(4 bytes) + DataLen uint32(4 bytes) dataLength uint32 = 4096 // data length ) type Message struct { MID uint32 Len uint32 Data []byte } func ReadMessage(conn net.Conn) (Message, bool, error) { header, err := io.ReadAll(io.LimitReader(conn, int64(headLength))) if err != nil { return NoneMessage, true, err } // if the header has no data, we can consider it as a closed connection if len(header) == 0 { return NoneMessage, true, cerr.PacketConnectClosed } msg, err := parseHeader(header) if err != nil { return NoneMessage, true, err } msgData, err := io.ReadAll(io.LimitReader(conn, int64(msg.Len))) if err != nil { return NoneMessage, true, err } msg.Data = msgData return msg, false, nil } func parseHeader(header []byte) (Message, error) { msg := Message{} if len(header) != headLength { return msg, cerr.PacketInvalidHeader } bytesReader := bytes.NewReader(header) err := binary.Read(bytesReader, endian, &msg.MID) if err != nil { return msg, err } err = binary.Read(bytesReader, endian, &msg.Len) if err != nil { return msg, err } if msg.Len > dataLength { return msg, cerr.PacketSizeExceed } return msg, nil } func pack(mid uint32, data []byte) ([]byte, error) { pkg := bytes.NewBuffer([]byte{}) binary.Write(pkg, endian, mid) binary.Write(pkg, endian, uint32(len(data))) binary.Write(pkg, endian, data) return pkg.Bytes(), nil }