tcp重传机制 对端滑动窗口一直为0时如何处理?

有一个长连,应用层write 1K字节数据到os的socket buffer后,对端机器滑动窗口一直为0,或者发送一部分数据后,一直未收到ack,数据…
关注者
170
被浏览
40,294

7 个回答

在回答这个问题之前,先问一个问题,通信双方的客户端与服务器是AI机器人哇?不是!那是什么?是两个不够智能的僵硬机器,根据人类的指令输入来完成通信。

通信过程繁复兀杂,但拨开云雾会发现,其实通信过程可以分为两大类:

1)事件触发(event trigger) 简称ET
2)定时器触发 ( timer trigger) 简称 TT

我们以一个例子(TCP建立连接的三次握手)来说明两者的区别:

1.1 事件触发

A主动发起对B的TCP连接(SYN),这是ET还是TT呢? 是ET,因为是位于A后的老王发出的指令,比如在浏览器里输入B 的网址,然后触发TCP连接

1.2 定时器触发

但是如果SYN在发给B 的过程中丢了呢?是否还需要老王再次提交指令?如果是,那这个TCP协议栈就太不友好了,事实上商用的TCP会缓存用户的连接指令,并启动一个重传定时器,定时器超时,无需老王的干预,TCP会自动重传连接指令,这就是定时器触发

2.1 事件触发

假设B接收到A的连接请求,这个就是事件触发,是由于外部事件而触发的动作,动作是什么呢? 发SYN + ACK。

2.2 定时器触发

B同样担心自己的SYN + ACK丢失,所以也会启动一个重传定时器,如果在超时时间内没有接收到A的ACK,则会触发重传动作,如果收到ACK,则关闭定时器。

3 事件触发

假设A接收到B的SYN + ACK,这是一个外部事件触发的动作,动作是

1)关闭重传定时器

2)发送ACK

3)将TCP状态更新为established

对于3.2里的ACK要不要启动重传定时器?不需要,如果是,会无限循环到永远。

以上通过3-way 握手解释了事件触发以及定时器触发的区别,对于题主的问题就非常好回答了。

对于应用层提交给TCP的数据(事件触发),触发的动作是

1)发送数据 并缓冲数据

2)为数据启动重传定时器

如果接到对方ACK,事件触发的动作是

1)关闭定时器

2)释放缓存

如果定时器超时也没有接收到ACK,则定时器触发,动作是

1)重传数据

2)记录重传次数

如果重传次数满,比如重传8次,则是事件触发,动作是

1)reset 或关闭TCP连接

2)通知应用层出错

再来回答第二个问题,B告诉A,window size =0,则A认为这是一个外部事件,触发一个动作

1)启动探测定时器( persistent timer)

如果在PT超时之前接收到B的window >0, 则事件触发,动作为

1)关闭PT

2)有数据则继续发送数据

3)更新自己的滑动窗口右侧

如果在PT超时之前没有接收到B window更新,则定时器触发,动作为

1)发送一个byte 合法数据(滑动窗口内)或非法数据(滑动窗口外)

2)刷新定时器

3)记录超时次数

如果超时次数到达极限,则事件触发,动作为

1)reset 或关闭TCP连接

2)通知应用层出错原因

总结

整个通信过程 只需要一次用户输入(用户事件),接下来的通信过程全部依赖事件触发、定时器触发而产生的动作自动完成 ,或如行云流水(顺利)或磕磕绊绊(不顺利),但无需用户干预。

编辑于 2017-08-29 23:46

你可以很容易地重现这个场景,再用 tcpdump 看看就知道了。