免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: jiufei19
打印 上一主题 下一主题

TCP协议中Window Scale Option问题【完全解决】 [复制链接]

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-11-17 06:20:00
21 [报告]
发表于 2010-01-20 12:01 |只看该作者

回复 #19 eexplorer 的帖子

经过和eexplorer的探讨,我昨天仔细将他的说明和自己的考虑重新认真思索了一遍,终于彻底解决了2**31的问题,下面我将分析详细说明如下,希望能给大家帮助(假如没有错误的话:" />:" /> )

1、参考图1


1、下面我们分析下对应2**32的序号空间,究竟发送和接收窗口需要多大?
a)我们首先假定滑动窗口大小刚好容纳整个32bits序号空间,于是表示当发送方没有是收到接收方的ACK之前,最多可以发送2**32字节数据
b)本图为初始连接的状态
c)假定发送方发送了2**32字节数据后,尚未收到接收方的任何ACK,于是发送方开始等待,也即snd.una=1(不失一般性,假定SYN分段序号为0)
d)因为已经发送了2**32字节数据,所以下一次发送的分段的序号将从0重新开始,并且我们假定在某个时刻发送方收到了接收方发回的ACK,该ACK确认了头1000个字节的数据,并且1001开始的部分分段可能正在途中(被delayed),我们不妨假定正好1001-2000的分段被延迟了,尚未到达接收方
e)因为发送方收到了ACK1000,于是发送方可以继续发送新的分段,这里一定要注意,发送方可以发送的新的数据量并不是只限1-1000这1千字节,因为究竟可以发送多大数据量取决于此ACK1000种所携带的窗口大小,而这个窗口大小又取决于接收方应用读取接收方TCP缓存的大小,显然这个读取的大小并不固定为1000字节,其实该大小和1000没有任何关系,完全是接收方应用的read行为,所以此时完全存在接收方应用所读的数据大于1000字节的情况,于是这个窗口的大小随ACK1000返回给发送方后,发送方此时就可能发送1001-2000开始的序号分段,那么问题就出现了,当新的1001分段发出后,将和老的1001分段序号完全相同,则接收方将如何判断哪个是old,哪个是new?另外,如果此时发送方因为超时而重发1-1000分段,那么同样因为接收方当前正准备接收1-1000分段,这样也造成了混淆,于是我们知道滑动窗口不可能和序号空间一样大

2、因为滑动窗口的大小必须是2的整数次幂,所以我们接下来分析是否可以为2**31

参考图2






a)上图显示了当滑动窗口为32bit序号空间一半的情况
b)同理按照刚才的分析,此时发送方在未收到接收方的ACK时,最多可以发送2**31字节数据,于是snd.una=1,此时发送方暂停发送
c)并且我们假定接收方全部正确收到了,于是我们有rcv.wup=2**31,接收窗口右边界=rcv.wup+rcv.wnd
d)因为发送方一直没有收到ACK,所以此时发送方可能超时然后重发认为丢失的那些分段,这些分段的序号从0-2**31-1不妨设为seq=0,那么问题就产生了,这个seq=0的分段对于接收方而言到底是old还是new
e)显然接收方无法正确判断!!!注意,这里的关键问题都是因为下一个要接收的正确分段序号已经开始回绕了,导致重发的分段和新发分段的序号可能重叠,所以解决问题的办法只有是想法让下一个准备接收的分段序号不和重发的分段重叠,或者反过来即便要重叠,则必须通过PAWS那样引入另外的参数来区别


3、既然2**31不能为滑动窗口的最大值,那么只能考虑2**30了,于是


参考图3

接前面的分析,因为滑动窗口的大小只能是2的整数次幂,所以目前只能为2**30,这样,我们就很自然得到下面这个结论
rcv.wup+rcv.wnd snd.una <= 2**31
此时因为下一个即将接收的分段序号没有到达32bit的最大值,所以不会出现回绕,则发送方此时只能是重发1-2**30内的序号分段,那么此时接收方就能轻易判断出此时发来的分段都是重复old分段


通过上面分析,我们就可以自然得出window scale option的因子最大只能是14bit了


再次感谢eexplorer的热心帮助!





[ 本帖最后由 jiufei19 于 2010-1-20 12:14 编辑 ]

论坛徽章:
0
22 [报告]
发表于 2010-01-20 22:00 |只看该作者
好绕。
滑动窗口一定要是2的幂次方吗?

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-11-17 06:20:00
23 [报告]
发表于 2010-01-20 22:50 |只看该作者

回复 #22 hritian 的帖子

我也不想这么绕,真希望大家能指出我是否分析有误哈

论坛徽章:
0
24 [报告]
发表于 2010-01-23 15:11 |只看该作者
不错,有真的研究精神。

学习。

论坛徽章:
0
25 [报告]
发表于 2010-01-23 17:09 |只看该作者
原帖由 hritian 于 2010-1-20 22:00 发表
好绕。
滑动窗口一定要是2的幂次方吗?


应该这么说,实际用的滑动窗口的大小并不一定是2^n。但是我们是在讨论最大允许的滑动窗口的大小,因为window scale option是一个shift count,
所以最大是64K << 16 = 2^32,接下来就是64K << 15 = 2 ^31...

而jiufei19的分析已经排除了2^32, 2^31两种情况。

我前面一直没完全同意jiufei19的结论也就是和你有一样的疑问,今天突然想到了原因

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-11-17 06:20:00
26 [报告]
发表于 2010-01-24 10:47 |只看该作者

回复 #25 eexplorer 的帖子

就是说,在讨论“最大取值”这个前提下,那么根据上面的分析,32,31均不可能,则只有30才是最大可能值了

论坛徽章:
0
27 [报告]
发表于 2010-12-15 14:32 |只看该作者
本帖最后由 kutong 于 2010-12-15 15:00 编辑

如果在一个MSL内发送了3.5G数据呢?接收方1G的窗口内还是可能有可能收到重发的序号为1的数据,照样分不清是新是旧.只要是快速的网络,必须引入时间戳才能解决问题.
2**31的问题参考 tcp/ip详解 卷2 24章,这些序号的比较是用补码来实现的,补码有一些很好的数学特性.

论坛徽章:
0
28 [报告]
发表于 2012-07-04 22:54 |只看该作者
回复 21# jiufei19


这有一个地方不明白,想请教一下。


d)因为发送方一直没有收到ACK,所以此时发送方可能超时然后重发认为丢失的那些分段,这些分段的序号从0-2**31-1不妨设为seq=0,那么问题就产生了,这个seq=0的分段对于接收方而言到底是old还是new?

我的理解是:这个时候接收方的窗口是从2**31--2*32-1,并不包含0的呀,所以对seq=0是直接丢弃呀。


论坛徽章:
0
29 [报告]
发表于 2013-12-26 13:25 |只看该作者
本帖最后由 uiojkl227 于 2013-12-26 14:42 编辑

回复 26# jiufei19


   
请问下,tcp sender在ack.syn宣告了win=0,在什么情况下sender不会发送window update报文呢?三次握手建立完毕。

发现timestamps的值如下

Timestamps: TSval 0, TSecr 0

是否会导致此问题呢?

论坛徽章:
0
30 [报告]
发表于 2016-10-17 19:20 |只看该作者
序号空间是2^31次方的问题,是由于tcp的序号比较方式,
参考《TCP/IP详解 卷二》 第24章 24.7 TCP的序号

通过序号比较来确定给定序号是新序号或重传序号。而比较a和b的序号大小 通过 a-b =a+(b的补码)运算,计算结果按有符号数判断,如果b位于a后面2^31范围内,结果为负,如果b位于a前面2^31范围内,结果为证,结果为负,说明a小于b,是新序号则接收,结果是正则是旧序号丢弃。
留有一半空间也可以缓解序号回绕问题,但网络足够快的话还是会回绕,解决回绕是通过时间戳来做。

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP