细说TCP的可靠传输、流量控制、拥塞控制

目录

  • TCP如何实现可靠传输?
  • TCP如何实现流量控制?(滑动窗口)
  • TCP如何实现拥塞控制?(慢开始、拥塞避免、快重传、快恢复)

引申:
1.UDP能否也实现可靠传输?
2.TCP为什么要三次握手、四次挥手?两次握手、3次挥手行不行?
3.什么情况使用UDP好、什么情况使用TCP好?

1. TCP如何实现可靠传输

TCP的可靠传输是基于连续ARQ协议的,ARQ协议中有两个重要的概念:滑动窗口累计确认。但是我认为TCP能实现可靠传输不仅仅是靠连续ARQ协议,还依靠了:
1.通过三次握手、四次挥手来保证信道的可连接性 ;
2.采用停止等待协议、连续ARQ协议(自动重传)来保证数据的正确性;
3.序列号和确认应答号保证了数据的有序性,
4.校验和:如果收到字节的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。

1.1 TCP三次握手的必要性

TCP通过三次握手来确定这是一个可靠的连接,三次握手的目的是为了确定客户端和服务端都有正常的【收发】能力,即客户端可以发送接收消息,服务器也可以发送接收消息。

三次握手

  • 第一次:客户端 → 发送请求 ( SYN = 1,syn = x )→ 服务端,服务端知道【客户端】可以【发送】消息;
  • 第二次:服务端 → 应答+请求 ( ACK = 1 , SYN = 1,syn = y , ack = x + 1)→ 服务端,客户端知道【服务端】可以【接收】自己的消息,并且知道它能【发送】消息;
  • 第三次:客户端 → 应答 ( ACK = 1,syn = x + 1 , ack = y + 1 )→ 服务端,服务端也确认【客户端】【接收】消息。

那么如果只有两次握手,则【客户端】【接收】能力并没有得到确认,不能确定这是一个可靠的连接。同时,为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤,如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认。

1.2 TCP为什么要4次挥手?

  • 因为TCP是一个全双工的链接,即客户端可以向服务器传送数据,服务器也可以向客户端传送数据。当客户端【请求】断开连接时,代表客户端需要向服务器发送的数据已经完毕,服务器【确认】收到断开连接,此时进行了两次挥手。 如果和建立TCP链接时一样立刻进行第三次挥手会出现一个问题:服务器需要向客户端发送的数据此时不一定全部发送完毕,这时需要等待服务器发送完送有的数据,才能进行下面的操作。
  • 当服务器也发送完所有的数据给客户端,才能进行后两次挥手。服务器向客户端发送一条断开连接的【请求】,客户端【确认】应答后,服务器立刻进入了CLOSED模式。
  • 此时客户端还不能立刻进入CLOSED模式,需要等待2MSL。原因:由于客户端最后一个ACK可能会丢失,这样B就无法正常进入CLOSED状态。于是B会重传请求释放的报文,而此时A如果已经关闭了,那就收不到B的重传请求,就会导致B不能正常释放。而如果A还在等待时间内,就会收到B的重传,然后进行应答,这样B就可以进入CLOSED状态了。
四次挥手

1.3 停止等待协议、连续ARQ协议、选择重传

这三个协议的目的,都是为了保证了客户端和服务器的数据,能确保传送到对面。如果数据在中途丢失或者延迟,则需要重新发送,一直到对面接收到为止。

停止等待协议:

A每发送完一个报文M,就等候B对其确认;如果没收到确认,则不能继续发送,收到确认后再继续发送。缺点是一个个字节发送效率太低。


停止等待协议

数组分组在传输过程中发生错误时有两种情况:

1、当接收方收到错误数据分组时,会直接丢弃分组。
2、如果数组分组在传输的过程中丢失。

在这两种情况下,接收方都不会发送任何信息。发送方在一定时间内没有收到确认,就认为分组丢失,然后重传该数据分组,这就叫超时重传。
停止等待ARQ协议就是通过这种确认和重传的机制,在不可靠的网络上实现可靠通信。

连续ARQ协议:

显然,每次只发送一个报文然后等待确认效率太低。连续 ARQ 协议可提高信道利用率。发送方维持一个发送窗口,凡位于发送窗口内的分组可以连续发送出去,而不需要等待对方确认。接收方一般采用累计确认,对按序到达的最后一个分组发送确认,表明到这个分组为止的所有分组都已经正确收到了。如果中间发生丢失包的情况,A需要回退到确认的报文重新发送。


连续ARQ协议

A的发送窗口大小是根据B接受窗口设置的。也就是说A发送的报文速度不能超过B处理报文的速度。
TCP中对于超时重传时间的选择是根据平均往返时间RTT来计算的。也就是说,如果A超过一个报文平均往返时间没有收到确认,就会重新发送报文。

选择重传:

选择重传ARQ协议是指在接收方收到未按序排列的数据流时,通知发送方重传缺失的数据,而不是重传全部数据。TCP数据段首部中添加选择确认选项SACK可以实现该目的。


选择重传

如图所示,假设上述分组都在发送窗口中,收到三个不连续的分组。三个分组的边界分别为:[4000,5001]、[6000,7001]、[8000,9001]。在建立TCP连接时,连接双方先商定好,在首部选项中加入“允许SACK”的选项。在之后的TCP报文段中增加SACk选项,以便接收方向发送方报告不连续的字节块的边界。
因为序号是32位,因此指明一个边界需要4个字节,说明一个字节块的边界需要8个字节。另外需要一个字节指明是SACK选项,一个字节指明这个选项的大小。TCP报文段首部选项最大为40个字节,因此最多指明4个字节块的边界信息。
TCP标准并未指明发送方应该如何响应SACK,因此大多数实现还是重传所有未被确认的数据分组。

2. TCP的流量控制

利用滑动窗口机制可以实现对发送方的流量控制。在TCP连接建立时,接收方会在确认报文段中给出自己接收窗口的大小。在每次发送确认报文时能够根据情况动态调整接收窗口的大小,并将告知发送方。如下图所示:

流量控制

  发送方发送序号从1开始的100字节的数据,接收方在确认报文中声明自身的接收窗口大小为300字节。之后发送方发送300字节数据,接收方在确认报文中声明自身接收窗口大小调整为50字节。发送方再发送50字节数据之后,收到接收方传来的确认报文,在该报文中声明接收窗口为0。
  在接收方接收窗口为0时,发送方不再发送数据,直到接收方发送确认报文表明窗口大小发生改变。可是这个确认报文不一定能够被发送方接收到,如果一旦该确认报文丢失,双方都将处于等待中,形成死锁。为防止这种情况出现,TCP规定在收到对方接受窗口为0时,启动一个坚持定时器周期性的发送探测报文,以确定对方接收窗口为0的状态是否改变。
  另外,TCP标准规定:接收方接收窗口为0时,不再接收正常数据,但是可以接收零窗口探测报文段、确认报文段、携带紧急数据的报文段。

3. TCP的拥塞控制

拥塞控制
  • 拥塞控制是指防止过多的数据注入网络中,这样可以使网络中路由器或者链路不致过载。现在通信线路的传输质量一般都很好,因传输出现差错丢弃分组的概率很小。因此,判断网络拥塞的依据就是出现了超时。
  • TCP进行拥塞控制常用的算法有四种:慢启动拥塞避免快重传快恢复
3.1 慢启动

当主机开始发送数据时,如果立即将较大的发送窗口的全部数据注入网路中,那么由于不清楚网络的情况,有可能引起拥塞。比较好的方式是试探一下,即从小到大逐渐增大发送端的拥塞控制窗口数值。cwnd以指数增长的形式增长。

3.2 拥塞避免
  • 当窗口值逐渐增大时,为了防止cwnd的增长导致网络拥塞,还需要一个变量——慢开始门限ssthresh。当cwnd以指数增长的形式增长到大于或等于ssthresh时,就不再采用慢启动算法,而是采用拥塞避免算法来进行拥塞控制。
  • 拥塞避免算法规定:每次收到一个确认时将cwnd增加1/cwnd个SMSS。即不再是像慢启动算法那样经过一轮传输cwnd翻倍了,而是经过一轮传输增加一个SMSS。这是一种加性增长的关系。
      当拥塞发生时(超时或收到重复确认),cwnd被设置为1个SMSS。ssthresh被设置为当前窗口大小的一半,但最少为 2个报文段。
3.3 快重传
  • 如果个别报文段在网络中丢失,网络并没有发生拥塞,这种情况下发送方收不到确认报文,在超时之后会重传该报文。发送方误以为网络发生拥塞,错误的启动慢开始算法,降低了传输效率。
  • 采用快重传算法可以让发送方尽早知道个别报文段的丢失。快重传算法要求接收方不要延时发送确认,即使收到失序的报文段也要立刻发送对已收到报文的重复确认。如下图所示:
快重传

接收方收到M1之后发送对M1的确认报文,M2报文丢失,之后接收方收到M3、M4、M5时每次都发送对M1报文的重复确认。快重传算法规定当收到三次重复确认后,发送方就认为M2报文段丢失,立即重传M2报文段。

  • 快重传算法并非取消了重传机制,只是在某些情况下更早的重传丢失的报文段(如果当发送端接收到三个重复的确认ACK时,则断定分组丢失,立即重传丢失的报文段,而不必等待重传计时器超时)。
3.4 快恢复
  • 当发送方连续收到接收方发来的三个重复确认时,就执行“乘法减小”算法,把慢开始门限减半,这是为了预防网络发生拥塞。
  • 由于发送方现在认为网络很可能没有发生拥塞,因此现在不执行慢开始算法,而是把cwnd(拥塞窗口)值设置为慢开始门限减半后的值,然后开始执行拥塞避免算法,使拥塞窗口的线性增大。

作者:白马笑西风
链接:https://juejin.cn/post/6844903799253909512

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容