• 协议-TCP协议-基础概念02-TCP握手被拒绝-内核参数-指数退避原则-TCP窗口-TCP重传


    协议-TCP协议-基础概念02-TCP握手被拒绝-TCP窗口

    参考来源:
    极客专栏-网络排查案例课》

    TCP连接都是TCP协议沟通的吗?

    不是
    在这里插入图片描述

    如果服务端不想接受这次握手,它会怎么做呢?

    在这里插入图片描述

    内核参数中与TCP重试有关的参数(两个)

    -net.ipv4.tcp_synack_retries:
    此参数控制当服务器发送SYN-ACK数据包后,如果未收到客户端的ACK数据包,服务器将重新发送SYN-ACK数据包的次数。默认值通常是5次。
    net.ipv4.tcp_syn_retries : 此参数设置在放弃回应一个TCP连接请求前,需要进行多少次重试。)

    在 Linux 中,这个设置是由内核参数 net.ipv4.tcp_syn_retries 控制的,默认值为 6,查看方法:
    $ sudo sysctl net.ipv4.tcp_syn_retries
    net.ipv4.tcp_syn_retries = 6

    net.ipv4.tcp_synack_retries 是Linux内核的一个参数,它决定了当服务器发送SYN-ACK数据包后,如果未收到客户端的ACK数据包,服务器将重新发送SYN-ACK数据包的次数。在建立TCP连接的过程中,服务器会发送一个SYN数据包来启动连接,然后等待客户端的ACK响应。如果服务器没有收到ACK,那么它会重试几次,这就是由 net.ipv4.tcp_synack_retries 参数控制的。
    这个参数的默认值通常是5,意味着如果服务器没有收到ACK,它会尝试重新发送SYN-ACK数据包5次

    TCP客户端未收到回应后进行的策略,重试-指数退避原则

    在这里插入图片描述

    握手请求一直没成功,
    第二列是数据包之间的时间间隔,也就是 1 秒,2 秒,4.2秒,8.2 秒,16.1 秒,33 秒,每个间隔是上一个的两倍左右。到第 6 次重试失败后,客户
    端就彻底放弃了。

    显然,这里的翻倍时间,就是“指数退避”(Exponential backoff)原则的体现。这里的时间不是精确的整秒,因为指数退避原则本身就不建议在精确的整秒做重试,最好是有所浮动,这样可以让重试成功的机会变得更大一些。

    TCP窗口

    接收窗口:它代表的是接收端当前最多能接收的字节数。通过 TCP 报文头部的
    Window 字段,通信双方能互相了解到对方的接收窗口。

    拥塞窗口:发送端根据实际传输的拥塞情况计算出来的可发送字节数,但不公开在报文中。各自暗地里各维护各的,互相不知道,也不需要知道。

    发送窗口:对方的接收窗口和自身的拥塞窗口两者中,值较小者。实际发送的在途字节数不会大于这个值。

    TCP窗口大小

    在这里插入图片描述

    在这里插入图片描述

    在说到 TCP 窗口的时候,一般都会提到一个很重要的概念:Window Scale。这是因为,TCP 最初是七八十年代的产物,1981 年 9 月定稿的RFC793才第一次正式确定了 TCP 的标准。当时的网络带宽还处于“石器时代”,机器的带宽只有现在的百分之一,那么 TCP 接收窗口自然也没必要很大,2 个字节长度代表的 65535 字节的窗口足矣。

    但是后来网络带宽越来越大,65535 字节的窗口慢慢就不够用了,于是设计者们又想出了一个巧妙的办法。原先的 Window 字段还是保持不变,在 TCP 扩展部分也就是 TCP Options 里面,增加一个 Window Scale 的字段,它表示原始 Window 值的右移位数,最高可以右移 14 位。

    如果你还没有完全忘记计算机课的基本知识,那么应该明白这是一个非常大的提升了(扩大了 2 的 14 次方,即 16384 倍)。16384 乘以 65535,这个数字就是 1G 字节,也就是说,一个启用了 Window Scale 特性的 TCP 连接,最大的接收窗口可以达到 1GB。可以说,这个数字至今都是够用的。

    ##TCP两种重传类型
    超时重传和快速重传

    我们先来学习下超时重传,Timeout Retransmission。在 TCP 传输中,以下两种情况,都可能会导致发送方收不到确认:
    报文在发送途中丢失,没有到达接收方,那接收方也不会回复确认包。
    报文到达接收方,接收方也回复了确认,但确认包在途中丢失。
    在这里插入图片描述
    没有收到确认怎么办?发送方为了避免自己陷入“尬等”的境地,选择在等待某段时间后重新发送同样这份报文,这个等待的时间就是重传超时,Retransmission Timeout,简称RTO。这个 Timeout 其实是基于一个计时器,在报文发送出去后就开始计时,在时限内对方回复 ACK 的话,计时器就清零;而如果达到时限对方还没回复 ACK 的话,重传操作就被触发。

    当然,超时重传也还是可能会丢包,此时发送方一般会以 RTO 为基数的 2 倍、4 倍、8 倍等时间倍数去尝试多次。

    快速重传
    上面的超时重传虽然避免了“干等”的尴尬局面,但不可避免地带来了另外的问题:“干等”的时间还是不短的,这段时间被白白浪费了。快速重传的出现就是为了解决这个问题。它的思路是这样的:如果对端回复连续 3 个 DupAck 即重复确认,我就把序列号等于这个ACK 号的包重传。

    超时重传和快速重传的特点

    对于超时重传:
    TCP 对于每条连接都维护了一个超时计时器,当数据发送出去后一定时限内还没有收到确认,就认为是发生了超时,然后重传这部分数据。
    RTO 的初始值是 1 秒(在发送 SYN 但未收到 SYN+ACK 阶段)。
    在连接建立后,TCP 会动态计算出 TRO。
    RTO 有上限值和下限值,常见值分别为 2 分钟和 200ms。
    实际场景中,RTO 为 200ms 出头最为常见。

    对于快速重传:
    快速重传的触发条件是:收到 3 个或者 3 个以上的重复确认报(DupAck)。
    在快速重传中,SACK(选择性确认)也起到了避免一部分已经到达的数据被重传。不过,也由于 TCP 头部长度的限制,SACK 只能放置 4 个块,再多也不行了。
    快速重传只要 3 个 DupAck 就可以触发,实际上我们还可能观察到远多于 3 个DupAck 的情况,这也是正常现象。
    Spurious 重传对 TCP 传输的影响比快速重传和超时重传小很多,总体来说是一种影响不大的重传。

  • 相关阅读:
    springboot解决跨域问题
    const和constexpr记录
    Elasticsearch:运用向量搜索通过图像搜索找到你的小狗
    SpringBoot项目的搭建
    手把手教你maven的安装与配置(windows)
    [附源码]Python计算机毕业设计Djangossm新能源电动汽车充电桩服务APP
    【JAVA】浅解线程池ThreadPoolExecutor的各个参数
    hadoop生态圈面试精华之zookeeper(三)
    ApacheDBUtils的使用
    Linux系统卡顿处理记录(Debian)
  • 原文地址:https://blog.csdn.net/qinaide56/article/details/133275072