/
message.go
81 lines (64 loc) · 1.58 KB
/
message.go
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
package simple
import (
"bytes"
"encoding/binary"
"io"
"net"
cerr "github.com/cherry-game/cherry/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
}