| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> 计算机网络 TCP 协议总结 -> 正文阅读 |
|
[系统运维]计算机网络 TCP 协议总结 |
TCP 相关知识TCP/IP 协议占据了互联网通信的一大半江山,特别像 TCP 这种保障端到端的可靠传输更是相当重要,关于它的实现也很复杂,今天介绍下关于 TCP 的相关重要知识。 我们先来看下 TCP 的头格式: 我们看到有一个 在上图中,我们会看到以下几个元素,它们是 TCP 协议对几个重要问题的保障:
TCP 状态流转协议之所以会存在,就在于双方需要互相配合协作,以确定哪个阶段该做哪些事情。在 TCP 协议总体划分为 (图片地址) TCP 的三次握手、四次挥手而在上面的状态流转中,最重要,也是经常会提起的关于连接建立的 从上面的流程图中,我们会发现对于 Client 端来讲,经历了一个请求-确认过程;对于 Server 端来讲,也经历了一个请求-确认过程。这就相当于双方都已经互相确认过眼神了。所以,三次握手对于连接的建立是刚刚好的。 如果我们只进行 2 次握手就建立连接,那么对于 Server 端来讲太容易建立起连接了,基本是有客户端过来,那么 Server 就要建立起连接了。这种情况就会导致连接成本太低,Server 端很容超负载。 至于在关闭连接时需要四次挥手,主要是因为 TCP 是 TIME_WAIT在四次挥手中,有一个状态是 之所以不立即关闭,主要为了让被动关闭方能有足够的时间接收到最后的 Ack 包,如果没有接收到,被动方就会重新发送 Fin 包,重新触发主动方发送最后的 Ack 包。这样的话,就能尽量保证被动关闭方尽快关闭连接了,毕竟主动关闭方需要承担起主要责任,所以会有 TIME_WAIT 的等待了。 另外一个原因也是怕当前连接立马释放,有一定概率会立马被使用到,就有可能产生包的混乱问题了。 TCP 重传TCP 发送的包都需要接收方进行一个 TCP 里的重传机制会有一个超时的判断,这个超时时间并不是很准确,或者说并不是很标准,毕竟不同的网络环境,包的到达情况都会是不一样的。 所以 TCP 会使用一个采样时间,先记录了正常情况下一个数据包从发送到响应确认这么一来一回的时间,即所谓的 对于重传机制,还有另外一种触发机制。上面的情况属于发送方去探知发送情况,也有另一种情况是接收方能探知的。比如发送方发送了 1, 2, 3 的包,但实际上接收方只接收到 1 和 3,一直没能收到 2 这个包,那此时接收方就会连续响应三个 关于 2 的 ack 包。 当发送方收到这么一个连续的 3 个 ack 包后,就知道需要重传 2 了,此时就不需要等到 2 的超时未确认触发,可以提前的重传 2 这个包了。 TCP 滑动窗口重传机制使得数据包能够可靠的传输,然而如果接收方数据处理能力有限,而发送方未能感应到这种情况,不停的发送数据包,则会增加接收方的压力,还会导致网络拥塞的发生。 为此,TCP 采用 在接收方这边的窗口称之为 在计算出可接收大小后,接收方就会将此值设置在 TCP 头部里的 Window 字段,然后响应回发送方,发送方也就知道了当前所能允许发送的数据包大小了。 在发送方这边的窗口称之为 但由于一个数据包的发送需要有一个 ACK 响应才算完整流程,所以对于这些“已发送未响应”的数据也应该纳入到发送窗口的管理,并且只有真的 ACK 响应回来,才能继续下个数据包的准备发送。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kEHXCz4h-1635260199451)(https://qcsdn.com/article/94767.html)]](https://img-blog.csdnimg.cn/img_convert/cb724c4210ceb584d1a7fdde7a4d21c7.png#pic_center) 需要注意的是,如果发送方接收到的 Window 大小为 0,则表示当前的接收方已经无能力处理新的包了,此时发送方就不会再下发数据了,直到接收方发送一个 但此时需要考虑一种情况,就是接收方由于网络问题没能将窗口通告送达发送方,那此时发送方就会一直干等着了.所以对于发送方来讲,会启动窗口探知动作,让接收方 ACK 它当前的接收窗口大小,如果超过 3 次的探知动作,则直接断开连接了。 TCP 的拥塞控制在一个复杂的网络环境中,数据包的传输不仅仅只涉及到端到端的,还可能会出现很多网络问题,导致包的堆积,影响了整体的传输速度。所以,TCP 协议需要将网络的阻塞情况考虑进来,避免加剧。这就是 TCP 的拥塞控制。 为此,TCP 协议抽象出了 由此可见,拥塞窗口的计算很重要,它将决定了数据包的发送大小。而关于拥塞窗口的计算,它将在几个场景里会涉及到,下面我们一一来分析。 MTU 和 MSS在分析拥塞窗口的具体场景之前,我们先来看看拥塞窗口的基本单位:MSS。MSS 表示 网络传输数据的最大值,如果 MSS 加上包头大小,则表示网络传输最大报文:MTU 了。 在 Internet 这种互联网中,一般 MTU 定义为 576 字节,减去 TCP、IP 的包头 40 字节,则可以得到 MSS = 536 字节的值;而在以太网这种局域网里,一般 MTU 会大点:1500 字节,MSS 为 1460 字节。 慢启动当连接建立完毕,开始传输数据时,TCP 协议规定不能一开始就发送大尺寸的数据包,这样避免了网络环境有问题时,新加入的连接加剧了拥塞状况。所以,对于新加入的连接而言,需要一点一点的增大数据量,这就是所谓的 其中,慢启动涉及的拥塞窗口计算过程如下:
拥塞避免从慢启动的算法来看,每经过一个 RTT 后,拥塞窗口 的增长速度将会变得很厉害,如果没有进行限制的话,那么很快就会占满带宽了。因此, TCP 协议使用了一个叫慢启动门限(ssthresh)的变量(一般取 65535 字节)。当 cwnd 超过该限制后,就会进入所谓的 在拥塞避免阶段,拥塞窗口的计算过程如下:
从上面的算法可以看出,进入拥塞避免阶段后,数据包的发送大小将呈线性增加了。通过这样的方式,使得 TCP 的传输在前期很快,然后再慢慢降下来,达到网络最佳值。 拥塞发生前面都是在避免拥塞的发生去动态调整拥塞窗口(cwnd)的,然而按照线性增长的趋势,始终会导致网络拥塞的。当发送拥塞(一般只要丢包,需要重传数据包就认为发送了拥塞)时,TCP 协议该如何处理呢?此处也算是 TCP 协议比较复杂的地方,因为它在不断的改进,也衍生出了很多版本,下面我们来看看这些不同版本的区别和处理吧。 Tahoe 版本Tahoe 版本是 TCP 的最早版本,当它发现需要进行重传动作,即触发了 RTO 超时或发送方收到三个重复 ACK 包时,此时会进行的动作为:
Reno 版本Reno 版本进行的动作为:
其中,快速恢复阶段的步骤如下:
NewReno 版本NewReno 是对 Reno 的改进,主要是优化了快速恢复阶段,在 Reno 版本中,所考虑的都是一个包的丢失情况。然而,在实际情况中,一次数据窗口的发送,是有可能出现很多数据包丢失情况的。 这样的话,就会触发多次的 cwnd 和 ssthresh 减半动作,一旦 cwnd 降到小于 3 时,即发送窗口会出现小于 3 的情形,此时将再也触发不了 3 次快速重传动作了,只能依赖 RTO 超时,而一般 RTO 的值是比较大(太小会经常触发重传)的,此时整个传输速度将会大大降低。 所以 NewReno 会在收到所有数据包的确认后才结束快速恢复阶段,这样 cwnd 和 sshthresh 就不会轻易被降低了。 NewReno 主要是使用了一个 recover 变量,作为当前数据窗口中,可能丢包的最大序号。即如果有丢包情况产生,并且大于当前的 recover 值,则会更新该值。 当收到接收方的 ack 后,会进行 ack_seq 的判断,如果 ack_seq > recover,此时就可以结束快速恢复阶段了;如果 ack_seq < recover,则意味着多包丢失,还不能结束快速恢复阶段。通过这样的控制,来提高了整个的吞吐量。 Nagle 算法下面我们来看看 TCP 里的其他经典算法:Nagle。Nagle 算法是一种通过减少小数据包的发送来提高 TCP 效率的机制。它会把多个小数据包合并到一个片段,并且等待满足一定条件后,再一起发送过去。具体的触发条件是:
当上述条件都未满足,但发生了超时(一般为 200ms),则立即发送。 对于 TCP 协议来讲,默认会启用 Nagle 算法,降低网络负载,减少网络拥塞,提高网络吞吐。 Delay AckDelay Ack 指延迟发送 Ack。在 TCP 的确认机制里,可以在通信过程中不对每一个 TCP 数据包进行单独的 ACK 包响应,而是在传输数据时,顺便把 ACK 信息随数据包一起发送,这样可以提高利用率。 如果在一定时间内(一般 40 ms)没有数据包要发送,那么就会单独的进行 ACK 包响应。这个过程就被称为 Delay Ack 了。 粘包与拆包TCP 是面向字节流的传输,它会根据接收方的包处理能力以及当前网络的拥塞情况来一部分一部分的加载数据发送,再加上有 Nagle 这种整合小数据包的算法存在。所以对于接收方来讲,接收到的数据有可能是粘合在一起的,也有可能是被拆分开的,即所谓的粘包和拆包。 对于粘包和拆包现象,常用的解决方案有:
感兴趣的朋友可以搜一搜公众号「 阅新技术 」,关注更多的推送文章。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/15 22:52:44- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |