Golang Go语言中tcp服务器,如何解包超大数据包
如题,据说论坛日经月经都是 TCP 粘包?
参考了某论坛源码,直接贴链接不会被封号吧 某 csdn Golang 实现之 TCP 长连接-------服务端和客户端
/article/details/131402492
其中的解包核心代码
//如果消息体超过 4096(默认长度) var pack []byte if length > 4096 { pack = make([]byte, 0, int(length-1)) readableLength := length - 1 for { if readableLength < 4096 { slice := make([]byte, readableLength) _, err = reader.Read(slice) pack = append(pack, slice...) break } slice := make([]byte, int32(reader.Buffered())) _, err = reader.Read(slice) pack = append(pack, slice...) //更新可读长度 readableLength = readableLength - int32(len(slice)) } // buffer 返回缓冲中现有的可读的字节数,2+length+1 表示帧类型+数据长度+帧尾 } else if length < 4096 && int32(reader.Buffered()) < length-1 { //退回已读取的帧头 reader.UnreadByte() return Msg{Type: 1}, errors.New("数据长度不足") } else { // 读取剩余帧内容 pack = make([]byte, int(length-1)) _, err = reader.Read(pack) if err != nil { return Msg{Type: 1}, err } }
由于本人发送的消息体达到 2w ,进入第一个循环,打印出 len(slice),除了第一次有数据,后面 slice 长度全是 0 ,后面这个 pack 一直循环中,读取不到更多数据
求解?数据哪里去了,怎样能取出?
Golang Go语言中tcp服务器,如何解包超大数据包
更多关于Golang Go语言中tcp服务器,如何解包超大数据包的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
如果还停留在“粘包”这个概念,就该回去复习 computer network & TCP/IP 了,TCP 的抽象是 stream 也就是流,站在使用者的界面来看一定是流的 API 。
更多关于Golang Go语言中tcp服务器,如何解包超大数据包的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
我这也不是粘啊,大包分成快了吧,后面的包取不到
后面的可能就还没来
或者说还没过内核协议栈
要过了之后才能在应用层取到
先发送数据长度,再发送数据本体,就不会粘包了,建议有时间还是看看<<通信原理>>。
或者干脆直接用通信框架,比如 gRPC ,这样你就不需要学 tcp 也不需要学通信原理,直接用 RPC 框架帮助你发送数据就行。
可以看一下 websocket 的协议,简单但是完备
数据包太大了,只能接收头部一部分
没遇到过这种情况。第一个长度是多少?不如直接贴个 demo ,大家好分析,本地 s2s 也不麻烦
你把完整的 Server 与 Client 端的代码发出来看看。
楼主可以参考一下标准库里 io.ReadAll()的实现
先找个二进制协议模版看一下先,比如 dubbo 那个协议图就画得很好
分段传输,写到文件里
发送的时候先发比如 4 字节长度值为 20000 ,后面发 20000 字节数据。
读的时候,先读 4 字节,拿到长度 x ,再读后面 x 字节。
感谢,上了框架 go-netty ,问题解决,有空看看它是怎么实现的
在Go语言中处理TCP服务器时,解包超大数据包通常涉及到以下几个步骤:
-
使用缓冲读取:由于TCP是基于流的协议,数据可能以任意大小的分片到达。因此,你需要在接收端使用缓冲区来累积数据,直到你拥有完整的消息。
-
定义协议:在设计你的TCP服务器时,应明确数据包的格式和大小。例如,可以在每个数据包的开头添加一个固定长度的头部,用于指示后续数据的长度。
-
分帧和重组:实现一个逻辑来分帧(识别数据包的开始和结束)和重组(将分片的数据重新组合成完整的数据包)。这通常涉及读取头部信息,然后根据头部信息中指定的长度来读取剩余的数据。
-
处理粘包和拆包:TCP粘包和拆包问题是常见的挑战。你需要确保你的协议和代码能够正确处理这些情况,例如通过添加分隔符或使用固定长度的头部来标识消息的开始和结束。
-
错误处理:在解包过程中,应添加适当的错误处理逻辑,以便在数据不完整或格式错误时能够优雅地处理。
-
使用库:考虑使用现有的Go库来处理TCP通信,如
net
包,这些库提供了基本的TCP连接和数据读取功能,可以简化你的工作。
综上所述,处理超大数据包的关键在于设计一个健壮的协议,并使用适当的缓冲和逻辑来确保数据的完整性和正确性。