客户端与服务器之间的通信是一个数据传输过程。通信的消息将以数据包形式进行传输。

为了更有效地进行通信,TCP 协议在数据进行数据传输时,使用滑动窗口机制来同时发送多个数据包。当数据包丢失时,TCP 协议利用数据重发功能重新发送数据包。因接收端接收数据包的能力不同,TCP 流控制会根据接收端的能力发送适当数量的数据包。

数据分片

数据从主机传送到另一个主机往往要经过路由器、网关等设备。这些设备都要对经过的数据进行处理。由于这些设备处理数据有一定的限制,不能处理超过额定字节的数据,所以发送的时候需要确定发送数据包的最大字节数。

这个最大字节数被称为最大消息长度(Maximum Segment Size,MSS)。当要发送的数据超过该值,就需要将数据分为多个包,依次发送。该操作被称为数据分片。

MSS 是 TCP 数据包每次能够传输的最大数据量。通常,最大值为 1460 字节。如果发送的数据包大小大于 MSS 值,数据包将会被分片传输。分片原理如图所示。

其中,第 1 次和第 2 次握手包的 TCP 首部包含 MSS 选项,互相通知对方网络接口能够适应的 MSS 的大小,然后双方会使用较小的 MSS 值进行传输。

滑动窗口机制

在进行数据传输时,如果传输的数据比较大,就需要拆分为多个数据包进行发送。TCP 协议需要对数据进行确认后,才可以发送下一个数据包,如图所示。

从上图中可以看到,发送端每发送一个数据包,都需要得到接收端的确认应答以后,才可以发送下一个数据包。这样一来,就会在等待确认应答包环节浪费时间。为了避免这种情况,TCP引入了窗口概念。窗口大小指的是不需要等待确认应答包而可以继续发送数据包的最大值。

例如,窗口大小为 3,数据包的传输如图所示。

从上图中可以看到,发送端发送第一个数据包(1-1000),没有等待对应的确认应答包,就继续发送第二个数据包(1001-2000)和第三个包(2001-3000)。当收到第3个数据包的确认应答包时,会连续发送3个数据包(3001-4000,4001-5000,5001-6000)。当收到第6个数据包的确认应答包时,又会发送3个数据包(6001-7000,7001-8000,8001-9000)。

以这种方式发送,就可以省去多个数据包(第1、2、4、5、7、8个)的确认应答包时间,从而避免了网络的吞吐量的降低。

窗口大小指的是可以发送数据包的最大数量。在实际使用中,它可以分为两部分。第一部分表示数据包已经发送,但未得到确认应答包;第二部分表示允许发送,但未发送的数据包。在进行数据包发送时,当发送了最大数量的数据包(窗口大小数据包),有时不会同时收到这些数据包的确认应答包,而是收到部分确认应答包。

那么,此时窗口就通过滑动的方式,向后移动,确保下一次发送仍然可以发送窗口大小的数据包。这样的发送方式被称为滑动窗口机制。设置窗口大小为 3,滑动窗口机制原理如图所示。

上图中,每 1000 个字节表示一个数据包。发送端同时发送了 3 个数据包(2001-5000),接收端响应的确认应答包为“下一个发送4001”,表示接收端成功响应了前两个数据包,没有响应最后一个数据包。此时,最后一个数据包要保留在窗口中。

由于窗口大小为 3,发送端除了最后一个包以外,还可以继续发送下两个数据包(5001-6000 和 6001-7000)。窗口滑动到 7001 处。

数据重发

在进行数据包传输时,难免会出现数据丢失情况。这种情况一般分为两种。

  • 第一种,如果未使用滑动窗口机制,发送的数据包没有收到确认应答包,那么数据都会被重发;如果使用了滑动窗口机制,即使确认应答包丢失,也不会导致数据包重发。
  • 第二种,发送的数据包丢失,将导致数据包重发。

下面详细介绍使用滑动窗口机制的两种情况。

确认应答包丢失

这种情况指的是前面发送的数据包没有收到对应的确认应答。当收到后面数据包的确认应答包,表示前面的数据包已经成功被接收端接收了,发送端不需要重新发送前面的数据包了。如图所示。

下面分为 5 部分对上图进行讲解。

1) 发送端第 1 次发送数据包:这里设置的窗口大小为 3,可以最大发送 3 个数据包。发送端同时发送 3 个数据包 1-1000、1001-2000 和 2001-3000。

2) 接收端返回确认应答包:接收端接收到这些数据,并给出确认应答包。数据包 1-1000 和数据包 2001-3000 的确认应答包没有丢失,但是数据包 1001-2000 的确认应答包丢失了。

3) 发送端第 2 次发送数据包:发送端收到接收端发来的确认应答包,虽然没有收到数据包 1001-2000 的确认应答包,但是收到了数据包 2001-3000 的确认应答包。判断第一次发送的 3 个数据包都成功到达了接收端。再次发送 3 个数据包 3001-4000、4001-5000 和 5001-6000。

4) 接收端返回确认应答包:接收端接收到这些数据,并给出确认应答包。数据包 3001-4000 和数据包 4001-5000 的确认应答包丢失了,但是数据包 5001-6000 没有丢失。

5) 发送端第 3 次发送数据包:发送端收到接收端发来的确认应答包,查看到数据包 5001-6000 收到了确认应答包。判断第 2 次发送的 3 个数据包都成功到达了接收端。再次发送 3 个数据包 6001-7000、7001-8000 和 8001-9000。

发送数据包丢失

这种情况指的是发送端发送的部分数据包没有达到接收端。那么,如果在接收端收到的数据包,不是本应该要接收的数据包,那么就会给发送端返回消息,告诉发送端自己应该接收的数据包。

如果发送端连续收到 3 次这样的数据包,就认为该数据包成功发送到接收端,这时就开始重发该数据包。如图所示。

下面分为 7 部分对上图进行讲解。

1) 发送端发送数据包:这里窗口大小为 4,发送端发送 4 个数据包,分别为 1-1000、1001-2000、2001-3000 和 3001-4000。

2) 接收端返回确认应答包:接收端接收到这些数据,并给出确认应答包。接收端收到了数据包 1-1000,返回了确认应答包;收到了数据包 1001-2000,返回了确认应答包;但是数据包 2001-3000,在发送过程中丢失了,没有成功到达接收端。数据包 3001-4000 没有丢失,成功到达了接收端,但是该数据包不是接收端应该接收的数据包,数据包 2001-3000 才是真正应该接收的数据包。因此收到数据包 3001-4000 以后,接收端第一次返回下一个应该发送 2001 的数据包的确认应答包。

3) 发送端发送数据包:发送端仍然继续向接收端发送 4 个数据包,分别为 4001-5000、5001-6000、6001-7000 和 7001-8000。

4) 接收端返回确认应答包:接收端接收到这些数据,并给出确认应答包。当接收端收到数据包 4001-5000 时,发现不是自己应该接收的数据包 2001-3000,第二次返回下一个应该发送 2001 的数据包的确认应答包。当接收端收到数据包 5001-6000 时,仍然发现不是自己应该接收的数据包 2001-3000,第三次返回下一个应该发送 2001 的数据包的确认应答包。以此类推直到接收完所有数据包,接收端都返回下一个应该发送 2001 的数据包的确认应答包。

5) 发送端重发数据包:发送端连续 3 次收到接收端发来的下一个应该发送 2001 的数据包的确认应答包,认为数据包 2001-3000 丢失了,就进行重发该数据包。

6) 接收端收到重发数据包:接收端收到重发数据包以后,查看这次是自己应该接收的数据包 2001-3000,并返回确认应答包,告诉发送端,下一个该接收 8001 的数据包了。

7) 发送端发送数据包:发送端收到确认应答包后,继续发送窗口大小为 4 的数据包,分别为 8001-9000、9001-10000、10001-11000 和 11001-12000。

TCP 流控制

在使用滑动窗口机制进行数据传输时,发送方根据实际情况发送数据包,接收端接收数据包。但是,接收端处理数据包的能力是不同的。

1) 如果窗口过小,发送端发送少量的数据包,接收端很快就处理了,并且还能处理更多的数据包。这样,当传输比较大的数据时需要不停地等待发送方,造成很大的延迟。

2) 如果窗口过大,发送端发送大量的数据包,而接收端处理不了这么多的数据包,这样,就会堵塞链路。如果丢弃这些本应该接收的数据包,又会触发重发机制。

3) 为了避免这种现象的发生,TCP 提供了流控制。所谓的流控制就是使用不同的窗口大小发送数据包。发送端第一次以窗口大小(该窗口大小是根据链路带宽的大小来决定的)发送数据包,接收端接收这些数据包,并返回确认应答包,告诉发送端自己下次希望收到的数据包是多少(新的窗口大小),发送端收到确认应答包以后,将以该窗口大小进行发送数据包。

TCP 流控制过程如图所示。

为了方便讲解,将上图以发送端发送数据包进行分隔,将其分为 3 部分进行讲解。

第一部分

发送端根据当前链路带宽大小决定发送数据包的窗口大小。这里,窗口大小为 3,表示可以发送 3 个数据包。因此发送端发送了 3 个数据包,分别为 1-1000、1001-2000 和 2001-3000。

接收端接收这些数据包,但是只能处理 2 个数据包,第 3 个数据包 2001-3000 没有被处理。因此返回确认应答包,设置窗口大小为 2,告诉发送端自己现在只能处理 2 个数据包,下一次请发送 2 个数据包。

第二部分

发送端接收到确认应答包,查看到接收端返回窗口大小为 2,知道接收端只处理了 2 个数据包。发过去的第 3 个数据包 2001-3000 没有被处理。这说明此时接收端只能处理 2 个数据包,第 3 个数据包还需要重新发送。

因此发送端发送 2 个数据包 2001-3000 和 3001-4000。接收端收到这两个数据包并进行了处理。此时,还是只能处理 2 个窗口,继续向发送端发送确认应答包,设置窗口为 2,告诉发送端,下一个应该接收 4001 的数据包。

第三部分

发送端接收到确认应答包,查看到接收端返回窗口大小为 2。说明接收端接收了上次发送的 2 个数据包。此时仍然可以处理 2 个数据包,继续发送数据包 4001-5000 和 5001-6000。

如果在接收端返回的确认应答包中,窗口设置为 0,则表示现在不能接收任何数据。这时,发送端将不会再发送数据包,只有等待接收端发送窗口更新通知才可以继续发送数据包。

如果这个更新通知在传输中丢失了,那么就可能导致无法继续通信。为了避免这样的情况发生,发送端会时不时地发送窗口探测包,该包仅有1个字节,用来获取最新的窗口大小的信息。

原理如图所示。

下面介绍上图所示的获取窗口更新数据包的原理。

1) 发送端发送数据。发送端以窗口大小为 2,发送了 2 个数据包,分别为 4001-5000 和 5001-6000。接收端接收到这些数据以后,缓冲区满了,无法再处理数据,于是向发送端返回确认应答包,告诉它下一个接收 6001 的数据,但是现在处理不了数据,先暂停发送数据,设置窗口大小为 0。

2) 发送端暂停发送数据。发送端收到确认应答包,查看到下一次发送的是 6001 的数据,但窗口大小为 0,得知接收端此时无法处理数据。此时,不进行发送数据,进入等待状态。

3) 接收端发送窗口大小更新包。当接收端处理完发送端之前发来的数据包以后,将会给发送端发送一个窗口大小更新包,告诉它,此时可以发送的数据包的数量。这里设置窗口大小为 3,表示此时可以处理 3 个数据包,但是该数据包丢失了,没有发送到发送端。

4) 发送端发送窗口探测包。由于窗口大小更新包丢失,发送端的等待时间超过了重发超时时间。此时,发送端向接收端发送一个窗口探测包,大小为 1 字节,这里是 6001。

5) 接收端再次发送窗口大小更新包。接收端收到发送端发来的探测包,再次发送窗口大小更新包,窗口大小为 3。

6) 发送端发送数据。发送端接收到窗口大小更新包,查看到应该发的是 6001 的数据包,窗口大小为 3,可以发送 3 个数据包。因此发送了数据包,分别为 6001-7000、7001-8000 和 8001-9000。

TCP滑动窗口机制深度剖析相关推荐

  1. TCP滑动窗口机制(附图例)

    文章目录 前言 一.滑动窗口的引出 二.流量控制 2.1 16位窗口大小 2.2 发送缓冲区 2.3 逐步解析滑动窗口运作 三.快重传机制 四.拥塞控制(仅供参考) 五.延迟应答与捎带应答(略) 总结 ...

  2. TCP滑动窗口机制(重要)

    本文参考了一些优秀的书籍->图解TCP/IP,TCP协议卷一,小林coding,还有等等的知乎,百度. 小林coding  小林coding 知乎牛客的文章 : 万字长文 | 23 个问题 TC ...

  3. TCP滑动窗口模拟实战

    1.TCP滑动窗口机制 客户端与服务端之间的通信是一个数据传输的过程,消息以数据包形式进行传输. 在传输的过程中,通过滑动窗口机制来同时传输多个数据包:发送端根据接收端的处理能力,适当控制发送窗口大小 ...

  4. tcp欢动窗口机制_TCP 滑动窗口(发送窗口和接收窗口)

    TCP 滑动窗口(发送窗口和接收窗口) TCP的滑动窗口主要有两个作用,一是提供TCP的可靠性,二是提供TCP的流控特性.同时滑动窗口机制还体现了TCP面向字节流的设计思路. TCP的Window是一 ...

  5. 计算机网络:TCP滑动窗口的流量控制和拥塞控制

    1. 前言 最近在研究网络通信底层通信原理,所以不得不复习一波计算机网络传输控制协议.那么对于程序开发人员,了解底层网络通信原理,对于我们理解BIO.NIO网络通信十分重要.所以对于程序开发人员来说, ...

  6. TCP滑动窗口(发送窗口和接受窗口)

    TCP窗口机制 TCP header中有一个Window Size字段,它其实是指接收端的窗口,即接收窗口.用来告知发送端自己所能接收的数据量,从而达到一部分流控的目的. 其实TCP在整个发送过程中, ...

  7. TCP滑动窗口原理终于清楚了!

    我们在学习计算机网络的时候,遇到很多知识点.即便是背的滚瓜烂熟,让你去辨别知识点背后的深层逻辑的时候,可能就手足无措了. 比如小邱去面A公司的时候就被问到: 事实上,这个问题很大程度弥补我计算机网络的 ...

  8. TCP三次握手和四次挥手?TCP如何保证可靠性?什么是TCP滑动窗口?

    TCP三次握手和四次挥手? 三次握手 tcp3handshake.gif tcp3handshake2.gif tcp3handshake3.gif tcp3handshake4.gif 四次挥手 t ...

  9. TCP滑动窗口协议与流量控制

    谈到TCP的滑动窗口协议与流量控制,便会想起当年面试时的场景.那时刚刚毕业,匆匆学了一点TCP的皮毛,仅仅是知道了TCP是面向连接的协议,以对每个报文都进行确认+超时重传的机制来保证端到端的可靠传输: ...

最新文章

  1. 关于CSS样式浏览器兼容问题的一些注意事项
  2. Linux 自定义命令
  3. FFMpeg的基本介绍
  4. HttpClient 调用WebAPI时—传参的三种方式(ASP.NET MVCCORE均适用)
  5. exp导出excel oracle_如何从Oracle快速导出数据到Excel
  6. ubantu 添加防火墙策略_ubuntu安装防火墙并策略配置
  7. Windows下多线程的使用
  8. 4.16_template_method_行为型模式:模板方法模式
  9. setTimeout和setInteval
  10. 导出数据报ORA-39002: 操作无效 ORA-39070: 无法打开日志文件。 ORA-39087: 目录名 DUMP_DIR 无效...
  11. 176.第二高的薪水
  12. 手把手教你用WPE“修改”各种魔兽SF
  13. tensorflow中FLAGS全局变量用法
  14. socket服务器显示未响应,QTCPSOCKET 客户端已连接 而服务器无响应
  15. Spring boot + Sharding JDBC 分库分表 及 分布式事务处理
  16. 前端开发系列(十六)网页布局教程(2)
  17. 西门子杯电梯程序 六部十层电梯程序
  18. Java 求解买卖股票时机含冷冻期
  19. 【经历分享 工作体会 推荐】那些“资质平平”的计算机系学生,现在怎么样了?
  20. Sonicwall 防火墙说明书在线观看

热门文章

  1. 【Delphi】从内存读取或解压压缩文件(RAR、ZIP、TAR、GZIP等)(二)
  2. 诗与远方:无题(九十一)
  3. 小熊的人生回忆(六)
  4. IoC、Spring 环境搭建、Spring 创建对象的三种方式、DI
  5. 基于IDEA搭建JavaWeb入门项目结构(2021版)
  6. qt 工作流_助力提升企业生产力-工作流管理
  7. rocketmq常用命令
  8. python defaultdict 类属性_Python collections.defaultdict模块用法详解
  9. web.xml mysql_JSP登录验证脚本失败(mysql后端)web.xml servlet映射?
  10. python清除输出内容_jupyter notebook清除输出方式