feat(proto): 自 go-hua 迁入长度前缀封包协议编解码
- 8 字节头(4 字节 ID/校验 + 4 字节长度, 小端序) + CRC32 校验版本 - 附测试、examples/proto 例程与包 README(含 Decode reader 复用告诫)
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
package proto
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEncodeDecode(t *testing.T) {
|
||||
client, server := net.Pipe()
|
||||
defer client.Close()
|
||||
defer server.Close()
|
||||
|
||||
want := []byte("hello proto")
|
||||
go func() {
|
||||
data, err := Encode(want)
|
||||
if err != nil {
|
||||
t.Errorf("Encode: %v", err)
|
||||
server.Close()
|
||||
return
|
||||
}
|
||||
server.Write(data)
|
||||
}()
|
||||
|
||||
got, err := Decode(bufio.NewReader(client))
|
||||
if err != nil {
|
||||
t.Fatalf("Decode: %v", err)
|
||||
}
|
||||
if !bytes.Equal(got, want) {
|
||||
t.Errorf("Decode = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodeDecodeCrc32(t *testing.T) {
|
||||
client, server := net.Pipe()
|
||||
defer client.Close()
|
||||
defer server.Close()
|
||||
|
||||
want := []byte("hello crc32")
|
||||
go func() {
|
||||
data, err := EncodeCrc32(want)
|
||||
if err != nil {
|
||||
t.Errorf("EncodeCrc32: %v", err)
|
||||
server.Close()
|
||||
return
|
||||
}
|
||||
server.Write(data)
|
||||
}()
|
||||
|
||||
got, err := DecodeCrc32(bufio.NewReader(client))
|
||||
if err != nil {
|
||||
t.Fatalf("DecodeCrc32: %v", err)
|
||||
}
|
||||
if !bytes.Equal(got, want) {
|
||||
t.Errorf("DecodeCrc32 = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeCrc32Corrupted(t *testing.T) {
|
||||
client, server := net.Pipe()
|
||||
defer client.Close()
|
||||
defer server.Close()
|
||||
|
||||
go func() {
|
||||
data, _ := EncodeCrc32([]byte("payload"))
|
||||
data[len(data)-1] ^= 0xFF // 篡改数据
|
||||
server.Write(data)
|
||||
}()
|
||||
|
||||
_, err := DecodeCrc32(bufio.NewReader(client))
|
||||
if err == nil {
|
||||
t.Error("篡改数据后 DecodeCrc32 应返回错误")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodeHeaderFormat(t *testing.T) {
|
||||
// 头 8 字节:[0:4] 为 CRC/ID,[4:8] 为小端长度
|
||||
data, err := EncodeCrc32([]byte("abcd"))
|
||||
if err != nil {
|
||||
t.Fatalf("EncodeCrc32: %v", err)
|
||||
}
|
||||
length := int(data[4]) | int(data[5])<<8 | int(data[6])<<16 | int(data[7])<<24
|
||||
if length != 4 {
|
||||
t.Errorf("长度字段 = %d, want 4", length)
|
||||
}
|
||||
if len(data) != int(PakHeadLen)+4 {
|
||||
t.Errorf("报文总长 = %d, want %d", len(data), PakHeadLen+4)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user