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服务器
defer conn.Close()
收发数据:
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("####"))
代码:
package main
import (
"encoding/binary"
"fmt"
"log"
"net"
)
const REQ_GENRANDOM_APP = 0x2008
func main() {
//建立TCP连接
conn, err := net.Dial("tcp", "192.168.6.130:9166")
if err != nil {
log.Printf("%d: dial error: %s", 1, err)
return
}
log.Println(1, ":connect to server ok")
defer conn.Close()
var sendData = make([]byte, 28)
//以大端序写入总包长()
binary.BigEndian.PutUint32(sendData, uint32(24))
//写入appid字符串
copy(sendData[4:], []byte("1"))
copy(sendData[8:], "####")
//写入消息类型
binary.BigEndian.PutUint32(sendData[12:], uint32(REQ_GENRANDOM_APP))
binary.BigEndian.PutUint32(sendData[16:], uint32(0))
binary.BigEndian.PutUint32(sendData[20:], uint32(4))
//写入随机数长度
binary.BigEndian.PutUint32(sendData[24:], uint32(16))
fmt.Println("sendData", sendData)
//发送数据
rv, _ := conn.Write(sendData)
fmt.Println("sendLen: ", rv)
var recvData = make([]byte, 128)
//接收数据
recvLen, _ := conn.Read(recvData)
fmt.Println("recvLen: ", recvLen)
fmt.Println("recvData", recvData[:recvLen])
return
}
成功连接到服务器,并获得16字节的随机数:
补充:还有一种序列化数据包的方法,是通过bytes.Buffer去做的,也挺好用的。