首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TCP速度慢?注意WS窗口因子~

TCP速度慢?注意WS窗口因子~

原创
作者头像
陈佳
修改2019-06-30 21:10:11
7.6K0
修改2019-06-30 21:10:11
举报
文章被收录于专栏:佳爷的专栏佳爷的专栏

【写在前面的话】

本文介绍一下Window Scaling的概念,以及配套的例子运用。转载请标明出处~~


【目录】

1、窗口因子介绍

2、案例介绍


什么是WS(window scaling)?

tpc有两个窗口,一个是滑动窗口,一个是拥塞窗口。WS与滑动窗口相关。通过增加一个因子来扩大默认滑动窗口的值。

滑动窗口的定义:收到ACK之前可以连续发送的字节数。举个例子,某接收端的窗口值假设为10240字节,假设发送端发的包每次都是1024字节大小,那么发送端可以连续发送10个包,而不需要收到接收端的ACK确认。

窗口大小占TCP头部16位,也就是窗口值最大能有:2^16=65535bytes=64K

65535字节到底有多大?在以前网速没有那么快的情况下是足够使用的,但是随着网速的不断提升,65535字节不够用了。

有个比喻叫填满水管(填网络链路)。自己按照理解画了张图。满打满算,水管的最大限度就是下图的矩形面积

有个计算方法: bandwidth * delay。带宽乘以延迟。

假设有两台主机连接在10Mbps的网络上,单程耗时是80ms。统一换算成字节。水管的面积就是:10,000,000bps/8bit*0.08秒=100,000bytes/s,也就是发送端可以连续发送100,000字节的数据给接收端。问题是刚才说了TCP的窗口大小最大只有65,535字节。也就是发送端尽全力发,最多也只有65,535字节可以发。

水管绿色部分就被浪费掉了。因此引入了WS,在tcp的option中增加16位作为滑动窗口因子window scaling。窗口值*窗口因子=最终的窗口值。但是并不是所有的客户端、服务端都支持窗口因子的。

为了更直观的看窗口因子,拿了两台服务器抓包。

【场景一】两端都支持窗口因子

窗口因子是在TCP三次握手时,SYN包进行同步的。

如上图,TCP第一个包:

10.123.4.10告诉10.123.4.4自己的窗口大小是29200,窗口因子是128。因此总大小是29200*128=3,737,600bytes这个值就远远大过默认的65,535bytes。

最底下的tcp option说明了窗口因子是7,2^7=128。这个128是算好了的,而且告诉你直接multiple 128。

TCP第二个包:

10.123.4.4告诉10.123.4.10,自己的窗口是28960,窗口因子是128。

【场景二】只有一端支持窗口因子

接下来我把10.123.4.4的窗口因子支持功能关闭。抓包如下:

还是一样,第一个包,10.123.4.10告知10.123.4.4自己的窗口大小是29200,同时窗口因子是128

第二个包,10.123.4.4告诉10.123.4.10,自己的窗口大小是28960,并没有什么窗口因子

第三个包,10.123.4.10也没有继续使用窗口因子了,最后红框可以看出(no window scaling used)

总结一下:

1、两端都支持,窗口因子才会最终被启用。如有一端不支持,则因子不会被使用。

2、窗口因子是在TCP的SYN包协商的,而且只协商一次。也就是滑动窗口是根据实际情况进行变化的,但是因子是固定的。


【一个案例】

用户访问源站速度正常,用户通过代理访问源站则速度慢

原因就在窗口因子上,代理和客户端本身支持窗口因子,但源站没有开启窗口因子协商。

在客户端直接访问源站的情况下,TCP三次握手情况如下,

客户端得知源站不支持窗口因子,于是接下来数据包的发送,滑动窗口的值就直接了当了。该给多少给多少。举个例子,原本客户端告知源站自己的窗口是1024,因子是1,总数就是1024*2^1=2048

但是从源站发回来的包得知源站并不支持因子,于是,接下来的包客户端在告知源站的时候,直截了当,窗口是2048。

客户端通过代理再去访问源站的情况如下:

客户端和代理都支持窗口因子,因此在step1的协商中,使用了窗口因子。且step1是优先于step2的。毕竟代理是先和客户端建联,然后在和源站建联。

但是在step2中,源站是不支持因子的,代理和源站之间协商的结果,没有使用窗口因子。

举个例子:

step1中,客户端告知代理,自己的win是1024,因子是1,总量就是1024*2^1=2048

step2中,代理告知源站一样的情况,win是1024,因子是1。但是源站不支持因子,于是就变成了,总量是1024。

于是,情况就变成了,前面的水管大,后面的水管小。整条链路上看,水管变小了。

【解决办法】

源站打开窗口因子的支持功能。

vim /etc/sysctl.conf

添加

net.ipv4.tcp_window_scaling = 1 #写入配置文件,永久生效

sysctl -p #立刻生效

sysctl -a | grep tcp_window #查看生效结果

参考资料:https://packetlife.net/blog/2010/aug/4/tcp-windows-and-window-scaling/

【后记】

江湖人称佳爷~~专注于解决公有云各类问题,喜欢讨论,欢迎来撩~~

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档