原创 吴就业 170 0 2023-10-27
本文为博主原创文章,未经博主允许不得转载。
本文链接:https://wujiuye.com/article/1503150405344fac8f027e01e16ccc8b
作者:吴就业
链接:https://wujiuye.com/article/1503150405344fac8f027e01e16ccc8b
来源:吴就业的网络日记
本文为博主原创文章,未经博主允许不得转载。
此为文章配套视频,如阅读本篇文章有不理解的地方,可观看此讲解视频!
自研实现文件上传下载的中间件在测试阶段发现断点续传有问题。具体表现是:使用wget下载mp4文件可以正常播放,用google浏览器打开链接,google浏览器无法正常播放mp4视频。
排查思路首先是打开浏览器的开发者工具视图,查看网络请求。发现浏览器一共发起两个请求,一个是不带Range的下载整个文件的请求,一个是带Range: bytes=0-
的http range请求,这两个请求都是响应2xx状态码。
请求状态码正常,那么只能抓包分析了。
通过tcpdump命令抓取这两个请求的数据包,然后用Wireshark工具分析。
不带Range的下载整个文件的请求,抓包结果如下:
其中36780端口是中间件服务的端口。从截图可以看出,是浏览器主动向服务端发起的断开连接,TCP报头标志位为[RST]。然后也能看出基本每个TCP数据包都重传了两次,客户端也重复ACK了两次,说明也没有丢包。
那为什么数据还没有传完,也没有什么异常,浏览器为什么要主动断开连接呢?
接着我们看带Range: bytes=0-
的http range请求,抓包结果如下:
基本跟前一个请求的表现一致,也是浏览器主动断开了连接,数据也没有传完。
我打算换个浏览器看看,然后我换成使用Safari浏览器。同样的,视频也无法在Safari浏览器上播放。
查看Safari浏览器的网络请求,同样也是发起了两次请求,一次是下载完整文件的请求,一次是http range请求。下载完整的文件请求,响应状态码是200,但为什么显示红色异常?而google浏览器是显示正常。
通过抓包分析后,其实与google浏览器的表现是一样的,也是浏览器主动断开的连接。
浏览器为什么会发起两个请求?感谢这篇文章:https://www.hustyx.com/misc/358/
我觉得这篇文章有些地方说的不对,因为从表现看对不上,下面是我个人理解的浏览器播放mp4视频的流程:
Google浏览器:
Range: bytes=0-
,服务端接收后会补齐终点位置,返回的是: Content-Range: bytes 0-end/total
,这样浏览器就拿到了总文件大小。浏览器不会等到接收完数据,不管响应的数据有没有接收完,他会立马断开连接,前一步下载整个文件请求的连接也会断开。Range: bytes=start-
(不指定end),start为上次接收到的位置,服务端每次都补齐end和total,返回状态码206,表示Partial Content,浏览器开始同步播放视频。循环反复直到文件下载完。Safari浏览器:
Range: bytes=0-1
,服务端接收后会补齐终点位置,返回的是: Content-Range: bytes 0-end/total
,这样浏览器就拿到了总文件大小。如果探测请求探测到服务端支持range协议,前一步下载整个文件请求的连接也会立即断开。Range: bytes=0-end
,浏览器不会等到接收完数据,接收一部分数据后他会立马断开连接。Range: bytes=start-end
,start接着前一次接收到的end位置开始(每一次取多少字节看不出规律)。循环反复直到文件下载完。到这就真相了,由于浏览器的探测请求不会等待所有数据响应完成,如果探测到服务端支持range协议,那么就会断开下个整个文件的请求的连接。
现在再来分析异常,我们从Safari浏览器的第二个请求发现了问题所在。
从截图可以看出,浏览器请求的range是0-1
,而服务端响应的是0-13250517/13250517
,而且end还错了,应该是文件大小减1。所以服务端处理分片下载的逻辑,响应头Content-Range是有问题的。
修复后视频就能正常播放了。
声明:公众号、CSDN、掘金的曾用名:“Java艺术”,因此您可能看到一些早期的文章的图片有“Java艺术”的水印。
了解网络协议、学会利用tcpdump抓包,学会利用Wireshark分析数据包,将能帮助我们解决一些仅从客户端日记分析或仅从服务端日记分析无法解决的疑难杂症。本篇结合笔者经历的一些实战案例,带大家掌握网络问题排查必备技能:tcpdump抓包分析。
在参与网络项目的研发,发现自己很多网络知识都不了解,在跨部门沟通时很是被动,需要补一些网络方面的知识。本篇我们一起从一个后端开发者的视角,理解带宽、以及内容分发网络CDN。
订阅
订阅新文章发布通知吧,不错过精彩内容!
输入邮箱,提交后我们会给您发送一封邮件,您需点击邮件中的链接完成订阅设置。
很好的文章, 如果能说明 chrome 、 safari 浏览器 第一次range探测使用head 还是 get 方法就更好了。
确实是。补充一下:都是GET请求。