golang实现TCP+序列化协议包

 

go语言的tcp通信代码还是比较简单的。

服务端:

listen, err := net.Listen("tcp", "0.0.0.0:8888") //tcp监听

defer listen.Close() //延时关闭listen

conn, err := listen.Accept() //等待连接

客户端:

conn, err := net.Dial("tcp", "127.0.0.1:8888") //连接到tcp服务器

收发数据:

conn.Read(buf)

conn.Write(buf)

本文重点不在这里,tcp简单demo参考链接:https://www.cnblogs.com/wind-zhou/p/12945288.html

 

下面进入正题

已知:有一个TCP服务器,原接口实现都是用C语言实现的,现在需要用go语言实现一个接口中间件。

比如,获取随机数的请求数据包格式如下所示,共28字节。(获取一个长度为16字节的随机数)


[]byte序列化核心就两点:
①向[]byte添加一个大端序的int
binary.BigEndian.PutUint32(sendData, uint32(24))

②向[]byte添加字符串
copy(sendData[8:], []byte("####"))
  

代码:

 1 package main
 2 
 3 import (
 4     "encoding/binary"
 5     "fmt"
 6     "log"
 7     "net"
 8 )
 9 
10 const REQ_GENRANDOM_APP = 0x2008
11 
12 func main() {
13 
14     //建立TCP连接
15     conn, err := net.Dial("tcp", "192.168.6.130:9166")
16     if err != nil {
17         log.Printf("%d: dial error: %s", 1, err)
18         return
19     }
20     log.Println(1, ":connect to server ok")
21     defer conn.Close()
22 
23     var sendData = make([]byte, 28)
24 
25     //以大端序写入总包长()
26     binary.BigEndian.PutUint32(sendData, uint32(24))
27     //写入appid字符串
28     copy(sendData[4:], []byte("1"))
29     copy(sendData[8:], "####")
30     //写入消息类型
31     binary.BigEndian.PutUint32(sendData[12:], uint32(REQ_GENRANDOM_APP))
32     binary.BigEndian.PutUint32(sendData[16:], uint32(0))
33     binary.BigEndian.PutUint32(sendData[20:], uint32(4))
34     //写入随机数长度
35     binary.BigEndian.PutUint32(sendData[24:], uint32(16))
36     fmt.Println("sendData", sendData)
37 
38     //发送数据
39     rv, _ := conn.Write(sendData)
40     fmt.Println("sendLen: ", rv)
41 
42     var recvData = make([]byte, 128)
43     //接收数据
44     recvLen, _ := conn.Read(recvData)
45     fmt.Println("recvLen: ", recvLen)
46     fmt.Println("recvData", recvData[:recvLen])
47 
48     return
49 
50 }

成功连接到服务器,并获得16字节的随机数:

 

补充:还有一种序列化数据包的方法,是通过bytes.Buffer去做的,也挺好用的。

 

 

 1 import (
 2     "bytes"
 3     "encoding/binary"
 4     "fmt"
 5     "log"
 6 )
 7 
 8 func main(){
 9     //序列化
10     var dataA uint64=6010
11     var buffer bytes.Buffer
12     err1 := binary.Write(&buffer, binary.BigEndian, &dataA)
13     if err1!=nil{
14         log.Panic(err1)
15     }
16     byteA:=buffer.Bytes()
17     fmt.Println("序列化后:",byteA)
18 
19     //反序列化
20     var dataB uint64
21     var byteB []byte=byteA
22     err2:=binary.Read(bytes.NewReader(byteB),binary.BigEndian,&dataB)
23     if err2!=nil{
24         log.Panic(err2)
25     }
26     fmt.Println("反序列化后:",dataB)
27 }

 

posted on 2021-09-13 14:10  yuzyong  阅读(620)  评论(0编辑  收藏  举报