本文主要讲解“如何用go语言处理TCP拆包/粘包”。本文的解释简单明了,易学易懂。现在,请跟随边肖的思路,一起学习学习《如何处理围棋语言中的TCP拆包/卡壳》!
00-1010最近研究了go附带的rpc。看了一遍,我以为我会实现一个编解码器,就是自定义消息的序列化和反序列化。消息的序列化和反序列化涉及两个步骤:
1.从网络中读取数据并将数据写入网络;
2.根据获取的二进制数据反序列化,将现有对象序列化为二进制数据。在这个过程中,我们需要处理TCP的拆包和粘贴。
TCP的拆包/上胶也是网络编程中比较基础的问题,具体的含义和解决方法就不详细描述了。虽然实现应用层逻辑的程序员可能根本不需要关心这个,但是作为中间件的开发,出于学习go语言的目的,还是有点练习的。
part 1
TCP拆包卡顿解决方案:读取数据时,将读取的二进制数据划分到正确的位置。这里直接使用head body方法,即发送数据时,先将整个数据的大小追加到数据中,如下所示:
大小(2字节)|正文(大小字节)
这里,以数据包的大小为头。
注意:在这里给出的例子中,大小占2字节;大小占用的具体字节数可以根据实际情况确定。
part 2
服务器实施:
funcdoConn(connet。conn){ 0
var(
buffer=bytes . new buffer(make([]byte,0,buf _ size))//buffer用于缓冲读取的数据。
ReadBytes=make ([] byte,buf _ size)//Read bytes用于接收每次读取的数据,并在每次读取后将读取的字节添加到缓冲区中。
I sead=true////用于标识当前状态:是尺寸部分还是身体部分正在处理中。
BodyLen=0//表示正文的长度。
)
对于{ 0
//先读数据
读取字节数,错误:=连接。读取(读取字节)
伊弗。=零
日志。致命的
返回
}
buffer . write(read bytes[0: read bytenum])//将读取的数据放入缓冲区。
//然后处理数据。
对于{ 0
ifisHea
d {
if buffer.Len() >= HEAD_SIZE {
isHead = false
head := make([]byte, HEAD_SIZE)
_, err = buffer.Read(head)
if err != nil {
log.Fatal(err)
return
}
bodyLen = int(binary.BigEndian.Uint16(head))
} else {
break;
}
}
if !isHead {
if buffer.Len() >= bodyLen {
body := make([]byte, bodyLen)
_, err = buffer.Read(body[:bodyLen])
if err != nil {
log.Fatal(err)
return
}
fmt.Println("received body: " + string(body[:bodyLen]))
isHead = true
} else {
break;
}
}
}
}
func HandleTcp() {
listener, err := net.Listen("tcp", ":1234")
if err != nil {
log.Fatal(err)
return
}
log.Println("start listening on 1234")
for {
conn, err := listener.Accept()
if err != nil {
log.Fatal(err)
return
}
go doConn(conn)
}
}
client具体实现:
func SendStringwithTcp(arg string) error { conn, err := net.Dial("tcp", ":1234") if err != nil { log.Fatal(err) return err } head := make([]byte, server.HEAD_SIZE) content := []byte(arg) headSize := len(content) binary.BigEndian.PutUint16(head, uint16(headSize)) //先写入head部分,再写入body部分 _, err = conn.Write(head) if err != nil { log.Fatal(err) return err } _, err = conn.Write(content) if err != nil { log.Fatal(err) return err } return nil }
感谢各位的阅读,以上就是“go语言如何处理TCP拆包/粘包”的内容了,经过本文的学习后,相信大家对go语言如何处理TCP拆包/粘包这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/140963.html