最近项目中遇到了问题,会偶然出现服务端返回不是客户端请求报文的情况

经过排查后发现,是客户端的http长链接网络库,在第一次发送超时的情况下,没有断开连接,而是用此长链接继续发送,

A包发送但超时未响应,然后发送B包,这时收到了A包的响应,则就会认为A包的响应为B包的响应内容,这就导致了此后的http请求和响应都不对应的情况。

关于http长链接,也是很有学问的

只有上一次的请求的回应数据完全接收后(根据 Content-Length 头部),才能进行下一次的请求。 也就是说,连接实际上是一个阻塞 loop,所以才需要有“连接池”的存在,不断的创建新的 TCP 链接,来实现请求的并发

服务端使用“队首阻塞”的概念,确实解决了请求排队等待的问题!

由这个问题,也想到了为什么网络上有那么多“TCP 粘包”的问题了。
因为 HTTP 1.0/1.1 协议使用了简单的纯文本来通信,而不是二进制,导致了很多人就认为 HTTP 就是 "TCP + 纯文本",进而想到需要如何解决边界定位问题,也就是所谓的“粘包”

由此可见,HTTP 2.0 才是正常的 ISO 七层协议的实现,增加了第六层表示层
如果一开始就接触 HTTP 2.0,也就不会有所谓的“粘包”问题了,因为TCP发送数据时,数据本身就是结构化数据,实现了自我的边界定位!

 

http 1.1的长链接,除增加连接池技术,服务端多次接收请求FIFO技术外,还可以使用报文头部加rrid技术,来标识请求和对应的关系

发布评论

分享到:

IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

linux gstack pstack 进程运行堆栈查看工具 strip详解
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。