189 8069 5689

go语言中tcp协议粘包 go tcp粘包

Golang 解决TCP“粘包“问题

TCP 协议是面向连接,可靠的流式协议,当 Server 去 Read 的时候,每次读到的数据都不一定是完整的,该方法会返回读到的字节数,因此,当我们写 Server 的时候,什么时候去回调用户设置的 callback ?也就是怎么样保证每次都能拿到一个完整的包数据,这个就是”粘包“问题的由来。

创新互联专业为企业提供建昌网站建设、建昌做网站、建昌网站设计、建昌网站制作等企业网站建设、网页设计与制作、建昌企业网站模板建站服务,十年建昌做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。

传统的,有两种方法解决。一是分隔符协议,即每条消息结尾设置固定分隔符,Server 读到分隔符就认为读到了完整的包数据;二是长度协议,即在每个消息头部设置固定长度的字段,表征消息长度,再往后读取该长度的消息即可。

目前长度协议用的较多,因为分隔符协议需要 Server 不停的检测,很耗费性能。长度协议实现中比较重要的点是头部的长度以及字节序, 2 个字节可表示 2^16-1 个字节的内容,如果不够,那就上4字节,字节序相关的只是可以参考: ”字节序“是什么鬼?

先来个没处理粘包的:

common/server.go:

测试一下:

因为每次只读5个字节,可以明显看到消息”乱了“,但就算把这个值增大,你只要是设置了,就会存在这个问题。

delimeter/server.go:

还是拿上个测试脚本跑,结果:

这次看到每个消息长度不一样,但是都是”完整的“。

length/server.go:

client 也得相应调整:

测试结果:

效果跟分隔符协议一样,都可以解决”粘包“问题。

只要是 TCP 协议,任何语言都需要处理 ”粘包“ 问题,我们用 PHP 写一个客户端测试一下:

完美!

只有在直接使用 TCP 协议才存在 "粘包" 问题,其上层应用层协议比如 HTTP ,已经帮我们处理好了,无需关注这些底层,但是我们自己实现一个自定义协议,就必须考虑这些细节了。

2021-03-08

TCP协议下的粘包与拆包,如何解决

TCP协议下的粘包与拆包,如何解决一、粘包、拆包1.1 粘包原因1.1.1 滑动窗口1.1.2 Nagle算法1.1.3 应用层原因1.2 拆包原因1.2.1 滑动窗口1.2.2 MSS限制1.2.3 应用层原因1.2 Netty提供的解决方案二、自定义协议解决粘包、拆包2.1 自定义协议要素

因为TCP/IP在起初,所有的请求是串行化的,之后做成了滑动窗口的概念。那么在接收方,如果接收不及时且窗口大小足够大,就可能出现粘包的情况。

因为每次数据发送的时候,都需要加上消息头等特殊数据,TCP与IP协议分别会加20Byte数据,因此哪怕只是发送1Byte数据,最终接收方还是会接收到41Byte;在这样的背景下,Nagle算法可能会将多个数据包合并在一起发送。

接收方ByteBuf设置太大(Netty默认为1024Byte),因此如果客户端发送的报文都非常小,抛开上述 1.1.1.1 中的原因不谈,光在Netty这一处也非常容易出现粘包现象

假设接收方的窗口只剩128Bytes,发送方的报文大小是256Bytes,这时放不下了,只能先发送前128Bytes,等待ack后,窗口有剩余空间了才会发送剩余部分,这就导致了拆包

当发送数据超过MSS限制后,会将数据切分发送,而这个MSS是根据不同类型网卡的限制来看,譬如某笔记本网卡可以发送1500Byte,除去一次数据包中的TCP/IP固定40Byte外,真正的数据也只能发送1460Byte。

Netty中ByteBuf设置的大小小于数据包大小。

未完待续... ...

socket 通信粘包怎么处理

一、socket 通信粘包的处理方法:

1、对于发送方引起的粘包现象,用户可通过编程设置来避免,TCP提供了强制数据立即传送的操作指令push,TCP软件收到该操作指令后,就立即将本段数据发送出去,而不必等待发送缓冲区满;

2、对于接收方引起的粘包,则可通过优化程序设计、精简接收进程工作量、提高接收进程优先级等措施,使其及时接收数据,从而尽量避免出现粘包现象;

3、由接收方控制,将一包数据按结构字段,人为控制分多次接收,然后合并,通过这种手段来避免粘包。

二、实现代码:

三、方法注意事项:

1、第一种编程设置方法虽然可以避免发送方引起的粘包,但它关闭了优化算法,降低了网络发送效率,影响应用程序的性能,一般不建议使用。

2、第二种方法只能减少出现粘包的可能性,但并不能完全避免粘包,当发送频率较高时,或由于网络突发可能使某个时间段数据包到达接收方较快,接收方还是有可能来不及接收,从而导致粘包;

3、第三种方法虽然避免了粘包,但应用程序的效率较低,对实时应用的场合不适合。

四、实验环境

1、硬件环境:服务器:pentium 350 微机 、客户机:pentium 166微机、网络平台:由10兆共享式hub连接而成的局域网;

2、软件环境:操作系统:windows 98 、编程语言:visual c++ 5.0


当前名称:go语言中tcp协议粘包 go tcp粘包
转载来于:http://jkwzsj.com/article/dddogsg.html

其他资讯