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 }