欢迎光临
我们一直在努力

TCP协议:流量控制,拥塞控制,延迟应答,捎带应答,TCP小结,TCP异常情况

🎬 胖咕噜的稞达鸭:个人主页

🔥 个人专栏: 《数据结构》《C++初阶高阶》 《Linux系统学习》 《算法日记》

⛺️技术的杠杆,撬动整个世界!


流量控制

接收端的接收能力是有限的,如果发送端发送太快,导致接收端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包,引起丢包重传等反应。

因此TCP支持根据接收端的处理能力,来决定发送端的发送速度,这个机制就是流量控制。

再回到三次握手,当第三次客户端发送出了ACK,就可以 携带数据捎带应答了,但是第一次第二次不可以携带数据,因为第一次SYN,SYN+ACK的时候处于建立连接的过程,对双方来说通信还没有建立成功,不可以携带数据。 前两次的缓冲区是空的,SYN,SYN+ACK的时候会交换缓冲区的大小,便于后续进行流量控制。

说明:

接收端将自己可以接收的缓冲区的剩余空间的大小放入TCP首部中的“窗口大小"字段,通过ACK端通知发送端;

  • 窗口大小的字段越大,说明网络的吞吐量越高;
  • 接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置为一个更小的值通知给发送端;
  • 发送端接受这个窗口之后,就会减慢自己的发送速度;
  • 如果接收端的缓冲区满了,就会将窗口设置为0,这时发送端将不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端。
  • 问题:接收端如何把窗口大小告诉发送端呢?

    正常情况下:接收端通过 TCP 报文的 16 位窗口字段,随普通报文主动告知发送端窗口大小; 还有PSH(PSH:通知对端应用程序立即把数据从TCP缓冲区中读走,把缓冲区中的数据尽快交给上层)

    异常情况下:当接收端过了重发超时的时间以后还是没有收到窗口更新的通知,发送端就会发送一个窗口探测的包,接收端主机的缓冲区在满的时候,就会发送一个窗口更新通知的包,一旦这个窗口更新的包丢失了,接收端就会一直发送窗口探测包,会影响双方的通信。

    [图片]

    问题:窗口大小是固定的吗?16个字节,2的16次方,一定是65535吗?

    实际上, TCP首部40字节选项中还包含了⼀个窗口扩大因子M, 实际窗口大小是窗口字段的值左移 M 位。 [图片]

    拥塞控制

    暂时无法在飞书文档外展示此内容 暂时无法在飞书文档外展示此内容

    问题:慢启动算法是什么?

    TCP引入慢启动机制,先以2的n次方的方式发送少量的数据,探探路,摸清了当前网络拥堵状态,再决定按照多大 的速度传输数据。

    前期所有客户端都会慢慢发,不会一次性发太多,如果客户端发送一个报文,接收到了服务器的ACK应答,网络没那么拥堵了,那么要尽快恢复网络通信的过程。

    慢启动的含义就是:前期慢,但是增长速度非常快。

    问题:我们刚刚不是说,发送多少数据由滑动窗口决定的吗?慢启动算怎么回事啊?拥塞窗口的大小是固定的吗?

    滑动窗口 = 对方的接收能力 为了支持拥塞控制算法 – > 拥塞窗口;

    其实拥塞窗口是一个临界值(整数值),在值以内,网络大概率不需要拥塞,值以上,网络就可能拥塞了。 网络是变化的,就决定这个拥塞窗口的大小不是固定的,要更新变化。

    所以强调一下:滑动窗口 = min(对方win接收能力,拥塞窗口) 哪个最小就以谁为主,木桶效应。 所以这样的话,就既考虑了网络拥堵的问题,又考虑了对方接收能力的问题。

    问题:刚刚谈到了发送数据的时候会以指数的形式探索网络是否依旧是拥塞的,这个指数形式会一直进行下去吗?我们发送数据的时候,发送数据的量,会进行指数增长吗?

    发送数据的量不会一直进行指数增长,增大到一定程度,发送的时候还要看对方的接收能力。 拥塞窗口的大小不等于对方发送的数据量,拥塞窗口的大小不是一直指数增加的,刚刚要指数增长的时候,是以前期慢,后期增长速度快,为了探求并恢复网络通信;

    要不要增长,拥塞窗口本质上是衡量网络是否会拥堵的一个指标,网络会不会拥堵是随着网络的具体情况进行变化的。所以拥塞窗口的值会变化,因为网络的状态是不确定的。刚开始确实会指数增长,网络不拥堵的时候会指数增长转为线性增长。

    暂时无法在飞书文档外展示此内容

    这个网络拥塞的状态就像男女朋友之间的关系一样,有时候会持续升温,有时候也会降到冰点,需要持续探测。

    细节问题:拥塞窗口在线性探测的过程中,会一直增大吗?

    逻辑上将一直增大(网络好的时候),但是实际上不会一直增大的。

    当TCP通信开始后,网络吞吐量会逐渐上升,随着网络发生拥堵,吞吐量会立即下降; 少量的丢包,我们仅仅是触发超时重传机制,大量的丢包,我们就认为是网络拥塞。 拥塞控制,本质上是TCP协议想尽可能把数据传输给对方,但是又要避免给网络造成太大的压力。

    延迟应答

    延迟应答就有较大的概率让我更新出一个更大的滑动窗口,用于解决TCP的效率问题。

    如果接收数据的主机立刻返回ACK应答, 这时候返回的窗口可能比较小. • 假设接收端缓冲区为1M. 一次收到了500K的数据; 如果立刻应答, 返回的窗口就是500K; • 但实际上可能处理端处理的速度很快, 10ms之内就把500K数据从缓冲区消费掉了; • 在这种情况下, 接收端处理还远没有达到自己的极限, 即使窗口再放大一些, 也能处理过来; • 如果接收端稍微等⼀会再应答,比如等待200ms再应答, 那么这个时候返回的窗口大小就是1M; ⼀定要记得, 窗口越大, 网络吞吐量就越⼤, 传输效率就越高. 我们的目标是在保证网络不拥塞的情况下 尽量提高传输效率;

    问题:所有的包都可以延迟应答吗?

    不是;数量限制:每隔N个包就应答一次; 时间限制:超过最大延迟时间就会应答一次。

    捎带应答

    很多情况下, 客户端服务器在应⽤层也是 “一发一收” 的. 意味着客户端给服务器说了 “How are you”, 服务器也会给客户端回⼀个 “Fine, thank you”;那么这个时候ACK就可以搭顺风车, 和服务器回应的 “Fine, thank you” ⼀起回给客户端。 [图片]

    TCP小结

    为什么TCP这么复杂? 因为要保证可靠性, 同时又尽可能的提高性能. 可靠性:

    • 校验和 • 序列号(按序到达) • 确认应答 • 超时重发 • 连接管理 • 流量控制 • 拥塞控制

    提高性能:

    • 滑动窗口 • 快速重传 • 延迟应答 • 捎带应答

    其他:

    • 定时器(超时重传定时器, 保活定时器, TIME_WAIT定时器等) 出现粘包问题的原因是TCP是面向字节流的,明确报文和报文之间的边界,涉及到协议+序列和反序列化。

    问题:那么如何避免粘包问题呢? 归根结底就是⼀句话, 明确两个包之间的边界.

    • 对于定长的包, 保证每次都按固定大小读取即可; 例如上⾯的Request结构, 是固定大小的, 那么就从缓冲区从头开始按sizeof(Request)依次读取即可; • 对于变长的包, 可以在包头的位置, 约定⼀个包总长度的字段, 从而就知道了包的结束位置; • 对于变长的包, 还可以在包和包之间使⽤明确的分隔符(应⽤层协议, 是程序猿自己来定的, 只要保证分隔符不和正文冲突即可)。

    TCP异常情况

    进程终止: 进程终止会释放⽂件描述符, 仍然可以发送FIN. 和正常关闭没有什么区别. 关机之前,OS要关闭所有的进程,进行4次挥手。(我们打开很多的进程,关机的时候会有提示:检测到您的xx进程还没有保存,需要保存吗?类似于这样的一句话。) 机器重启: 和进程终止的情况相同. 机器掉电/网线断开: 接收端认为连接还在, ⼀旦接收端有写入操作, 接收端发现连接已经不在了, 就会进⾏reset. 即使没有写入操作, TCP自己也内置了⼀个保活定时器, 会定期询问对方是否还在. 如果对方不在, 也会把连接释放. 暂时无法在飞书文档外展示此内容 另外, 应用层的某些协议, 也有⼀些这样的检测机制. 例如HTTP长连接中, 也会定期检测对方的状态. 例如QQ, 在QQ断线之后, 也会定期尝试重新连接.

    经典面试题:用UDP实现可靠传输

    你可以这样答: UDP 本身是无连接、不可靠、不保证顺序的协议。 要让 UDP 实现可靠传输,核心思路就是在应用层自己实现 TCP 的可靠性机制,主要做这几件事:

  • 给每个数据包加序列号,用来标识包的顺序,避免重复、乱序。
  • 接收方收到后回 ACK 确认,告诉发送方“我收到了”。
  • 发送方设置超时重传,如果一段时间没收到 ACK,就认为丢包,重新发送。
  • 接收方做乱序重组,把收到的包按序列号排好再交给上层。
  • 还可以加上校验和保证数据完整性,以及滑动窗口提高传输效率。
  • 简单说:UDP 只负责发数据包,可靠性由应用层用 序列号 + ACK + 超时重传 来保证。

    如果面试官继续问:和 TCP 比有什么意义?

    你补一句:

    这种方式叫可靠 UDP(RUDP),好处是灵活、低延迟、无队头阻塞, 适合游戏、实时音视频、物联网这些既要快又要部分可靠的场景。

    超短一句话版(紧张时用)

    在应用层给 UDP 包加上序列号、确认应答 ACK、超时重传、乱序重排,手动实现可靠性。

    赞(0)
    未经允许不得转载:171主机测评 » TCP协议:流量控制,拥塞控制,延迟应答,捎带应答,TCP小结,TCP异常情况
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址