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 }