计算机原理探险系列(三)-- TCP数据传输

本文涉及的产品
数据传输服务 DTS,数据同步 small 3个月
推荐场景:
数据库上云
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 计算机原理探险系列(三)-- TCP数据传输

上一篇文章中我们讲到了关于网络传输数据方面到内容,今天我们来深入了解下网络传输数据过程中可能会存在到问题。


数据包



正常到一次网络请求中,都会以数据包作为传输单位来判断。如果数据包到体积过大,那么就需要进行拆解。


tcp数据包信息基本结构如下:


网络异常,图片无法展示
|


包含了网络数据到发送端口,目标端口,ack,seq,还有一些和滑动窗口相关的数据信息。


mss值


mss值是一个缩写,全称是max segment size,主要是控制每次数据传输中的最大传输大小。每次进行数据包传输的时候,如果数据包大小超过了tcp里面限制的mss值,那么就需要分段传输,但是传输数据双方的mss值大小是不同的,因此最终分层传输是根据最小的mss值来限制。


如何达成通信双方的mss值大小约定?


在三次握手的时候会和服务端进行核对,并且达成一致协议。


握手建立的时候,通过wireshark抓包可以看到这option中mss参数:


网络异常,图片无法展示
|


mtu值


是网络传输过程中的最大传输单元,由于网络是分层传输数据的,因此不同层协议传输数据的时候都会有个最大传输单元的限制,也就是MTU(Maximum Transmission Unit,MTU)


在上一篇文章中我们有讲到过关于网络传输的细节点,在网络中传输数据的过程中,链路层主要是负责将数据包在不同的网关之间进行传输,不同的路由器它们之间的mtu大小是不一致的,所以在网络传输中,传输的性能主要取决于mtu最小的那台路由器。


如果MTU过大,在碰到路由器时会被拒绝转发,因为它不能处理过大的包。


场景思考:


当同一个网络上的两台主机互相进行通信时,该网络的MTU是非常重要。但是如果两台主机之间的通信要通过多个网络,每个网络的链路层可能有不同的MTU,那么这时重要的不是两台主机所在网络的MTU的值,而是两台主机通信路径中的最小MTU,称为路径MTU( Path mtu,PMTU)。


复杂场景的网络通信会是怎么样子的?


假设有一个场景下,a和b两台服务器需要进行网络通信,a需要先根据自己的路由设备的mtu计算出mss值。


通过以下方式可以查看到自己机器到mtu值


[root@izwz9ic9ggky8kub9x1ptuz ~]# cat /sys/class/net/eth0/mtu 
1500
复制代码


通常mss值为:MTU-20字节TCP报头-20字节IP报头得出,在以太网环境下,MSS值一般就是1500-20-20=1460字节。


通常在通信的发送端和接收端中间还有一系列复杂的路由器跳转,中间一旦出现任意机器上的mtu值小于传输数据包的体积值,那么就需要将该数据包进行遣返。这种情况我们一般称之为:PMTUD ( Path MTU Discovery )


ICMP错误报文


可以将它理解为个在网络链路传输中传输错误信息的一个角色。假设说在路由器的传输过程中出现了PMTUD情况,那么就需要返回一个ICMP错误报文包给到发送端,内部包含有具体的错误原因。


具体场景如下所示:


网络异常,图片无法展示
|


客户端在接收到对应的icmp错误报文之后,就会调整数据包体积的大小,然后进行数据包的分割,重新发送。


ICMP数据包也有可能会被误杀,有些网络管理员会在路由器、防火墙等中间设备上设置过滤ICMP报文的安全策略,这将导致ICMP差错报文被这些中间设备丢弃,无法达到发送方,从而引起PMTUD的失效。


现在有些厂商的路由器支持调整数据包的mss值,在进行传输数据的时候会动态调整数据包内option选项值的mss大小。


数据确认机制



在一次连接建立之后,客户端会给服务端发送相关的数据包信息,那么又该如何确认数据包是准确发送给到对方了呢?


RTO和RTT


RTT(Round Trip Time):一个连接的往返时间,即数据发送时刻到接收到确认的时刻的差值。


网络异常,图片无法展示
|


RTO(Retransmission Time Out):重传超时时间,即从数据发送时刻算起,超过这个时间便执行重传。


通常而言,RTO应当设置得比RTT略小一些,如果RTO小于RTT,那么可能会有重发情况发送,如果RTO太过大,那么有可能客户端会一直会处于等待状态,效率也不是那么高。


RTT和RTO 的关系

由于网络波动的不确定性,每个RTT都是动态变化的,所以RTO也应随着RTT动态变化。


SampleRTT

通常会选择一个已经发送但是未接受响应数据包的tcp连接作为参考对象,计算其RTT值来充当SampleRTT,这个SampleRTT会被代表所有连接的RTT。一旦该连接的ACK数据包返回之后,即可结束计时,得出SampleRTT值。


TCP维持一个估计RTT(称之为EstimatedRTT),一旦获得一个新SampleRTT时,则根据下式来更新EstimatedRTT:


EstimatedRTT = (1-a)* EstimatedRTT + a * SampleRTT

其中a通常取值为0.125,即:


EstimatedRTT = 0.875 * EstimatedRTT + 0.125 * SampleRTT
复制代码


数据接收窗口



通常在通信的双方都会各自维护一个网络窗口,用于处理数据包的接收。大体如下图所示:


网络异常,图片无法展示
|


tcp通信的双方都具有收发数据的能力,因此服务端和客户端之间都会各自维护接收窗口和发送窗口,并且随着窗口的大小通常都是处于一个约等于的状态,因为有可能某一段会在传输过程中对窗口的大小做调整(通过windows的参数来设置),然后该数值在传输过程中可能会有短暂的延时,因此我们说两端的窗口大小会有细微出入。


接收窗口和发送窗口


窗口只有在前面所有的段都确认的情况下才会移动左边界。当在前面还有字节未接收但收到后面字节的情况下,窗口不会移动,并不对后续字节确认。以此确保对端会对这些数据重传。如下图:


滑动窗口已经耗尽


网络异常,图片无法展示
|


滑动窗口仍有可用空间


网络异常,图片无法展示
|


流量控制


流量控制方面主要有两个要点需要掌握。一是TCP利用滑动窗口实现流量控制的机制;二是如何考虑流量控制中的传输效率。


所谓流量控制,主要是接收方传递信息给发送方,使其不要发送数据太快,是一种端到端的控制。主要的方式就是返回的ACK中会包含自己的接收窗口的大小,并且利用大小来控制发送方的数据发送。


这里面涉及到一种情况,如果B已经告诉A自己的缓冲区已满,于是A停止发送数据;等待一段时间后,B的缓冲区出现了富余,于是给A发送报文告诉A我的rwnd大小为400,但是这个报文不幸丢失了,于是就出现A等待B的通知||B等待A发送数据的死锁状态。为了处理这种问题,TCP引入了持续计时器(Persistence timer),当A收到对方的零窗口通知时,就启用该计时器,时间到则发送一个1字节的探测报文,对方会在此时回应自身的接收窗口大小,如果结果仍未0,则重设持续计时器,继续等待。


拥塞控制


拥塞的发生是因为路由器缓存溢出,拥塞会导致丢包,但丢包不一定触发拥塞。拥塞控制是快速传输的基础。由于tcp协议经常会发送不定长度的数据包,因此在网络中会有可能网络拥塞堵塞的情景。(当多个tcp同时并发进行请求的时候)。


市面上常见的拥塞算法有许多种,这里讲解最为经典的NewReno算法。


一个拥塞控制算法一般包括慢启动算法、拥塞避免算法、快速重传算法、快速恢复算法四部分。



不同拥塞算法慢启动的逻辑有所不同,经典的 NewReno 慢启动的算法如下:


连接建好的开始先初始化 cwnd = 10,表明可以传 10 个 MSS 大小的数据。

每当收到一个 ACK,cwnd 加 1。这样每当过了一个 RTT,cwnd 翻倍,呈指数上升。

还有一个 ssthresh(slow start threshold),是一个上限。当 cwnd >=ssthresh 时,就会进入“拥塞避免算法”。


Linux 3.0 后采用了 Google 的论文《An Argument for Increasing TCP’s Initial Congestion Window》的建议——把 cwnd 初始化成了 10 个 MSS。 而 Linux 3.0 以前,比如 2.6,Linux 采用了[RFC3390] 的建议,cwnd 跟 MSS 的值来变,如果 MSS < 1095,则 cwnd = 4;如果 MSS >2190,则 cwnd = 2;其它情况下,则是 3。


拥塞避免算法


当 cwnd 增长到 sshthresh 时,就会进入“拥塞避免算法”。拥塞避免算法下 cwnd 成线性增长,即每经过一个往返时间 RTT 就把发送方的拥塞窗口 cwnd 加 1,而不是加倍。这样就可以避免拥塞窗口快速增长的问题。


每收到一个 ack 时 cwnd 的变化:

cwnd = cwnd + 1 / cwnd

快速重传算法

快速重传算法主要用于丢包检测,以便能更快重传数据包,更早的调整拥塞状态机状态,从而达到持续升窗的目的。具体重传策略见第三节 重传机制。


快速恢复算法


当检测到丢包时,TCP 会触发快速重传并进入降窗状态。该状态下 cwnd 会通过快速恢复算法降至一个合理值。从历史发展来看,分为四个个阶段。


BSD 初始版本


收到 3 次重复 ACK,ssthresh 设为 cwnd/2,cwnd = cwnd / 2 + 3;

每收到一个重复 ACK,窗口值加 1;


收到非重复 ACK,窗口设为 ssthresh,退出

优点:在快速恢复期间,可以尽可能多的发送数据缺点:由于快速恢复未完成,尽可能多发送可能会加重拥塞。#### 5.4.2 [RFC3517]版本 1) 收到 3 次重复 ACK,ssthresh 设为 cwnd/2,cwnd = cwnd / 2 + 3; 2)每收到一个重复 ACK,窗口值加 1/cwnd; 3) 收到非重复 ACK,窗口设为 ssthresh,退出。


优点:在快速恢复期间,可以尽少量的发送数据(有利于拥塞恢复),且在快速恢复时间段的最后阶段,突发有利于抢带宽。


缺点:快速恢复末期的突发不利于公平性。


关于拥赛控制的实现算法还有很多种,这里贴出一条链接,感兴趣的朋友可以深入研究下:tcp拥塞控制详解【腾讯技术】

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
Sqoop 企业级大数据迁移方案实战
Sqoop是一个用于在Hadoop和关系数据库服务器之间传输数据的工具。它用于从关系数据库(如MySQL,Oracle)导入数据到Hadoop HDFS,并从Hadoop文件系统导出到关系数据库。 本课程主要讲解了Sqoop的设计思想及原理、部署安装及配置、详细具体的使用方法技巧与实操案例、企业级任务管理等。结合日常工作实践,培养解决实际问题的能力。本课程由黑马程序员提供。
目录
相关文章
|
6月前
|
网络协议 算法 安全
TCP/UDP 数据传输的链路解析
TCP/UDP 数据传输的链路解析
122 0
|
3月前
|
网络协议 安全 算法
"网络世界的守护者:一探究竟TCP协议如何确保数据传输的绝对安全与可靠"
【8月更文挑战第20天】传输控制协议(TCP)是网络通信中的核心协议之一,它确保数据包能可靠、有序地从源头传输到目的地。TCP采用三次握手的方式建立连接,并通过序列号、确认应答及超时重传来保障数据传输的准确性。此外,TCP还具备流量控制与拥塞控制功能,避免网络拥塞。虽然TCP在可靠性上表现优异,但在快速传输场景中可能存在局限。深入理解TCP对于网络工程师和开发者至关重要。
69 1
|
3月前
|
网络协议 安全
揭秘TCP背后的秘密:为何三次握手是连接的灵魂,四次挥手是告别的艺术,让数据传输稳如老狗!
【8月更文挑战第4天】TCP为何需三次握手和四次挥手?三次握手确保连接建立时双方均准备好并确认序列号,过程包括:客户端发SYN包;服务器回应SYN+ACK;客户端再回ACK确认,确保可靠通信。四次挥手则确保连接终止时双方能安全、有序地结束数据传输,包括客户端发FIN包;服务器回应ACK并可能继续发送数据;完成后发FIN包;客户端最终确认,确保无数据丢失或状态不一致。
77 9
|
5月前
|
网络协议 API 开发者
无线通信模块通过TCP/IP协议实现与PC端的数据传输
本文介绍了无线通信模块借助TCP/IP协议向PC端传输数据的过程,包括数据封装、发送和接收,并以WIFI模块为例,讨论了在QT平台下实现无线数据传输的方法。通过QTcpSocket类,开发者能轻松建立WIFI模块与PC间的连接。随着无线通信技术的进步,未来将有更多创新应用出现。
|
网络协议 安全 Linux
解密TCP连接断开:四次挥手的奥秘和数据传输的安全
本文将介绍TCP连接的断开过程,重点关注四次挥手的过程和状态变迁,以及为什么挥手需要四次和为什么需要TIME_WAIT状态。在TCP连接断开的过程中,双方需要发送FIN和ACK报文来确保数据的可靠传输和连接的正确关闭。挥手需要四次的原因是为了确保数据的完整传输和连接的可靠关闭。
769 1
解密TCP连接断开:四次挥手的奥秘和数据传输的安全
|
机器学习/深度学习 监控 网络协议
浅谈 TCP 握手/数据传输/挥手过程以及 tcpdump 抓包工具使用
浅谈 TCP 握手/数据传输/挥手过程以及 tcpdump 抓包工具使用
303 0
|
网络协议 Java
java实现TCP数据传输反馈
java实现TCP数据传输反馈
|
网络协议 Java
Java学习路线-39:网络编程TCP、UDP数据传输
Java学习路线-39:网络编程TCP、UDP数据传输
142 0
|
6月前
|
SQL 分布式计算 监控
在数据传输服务(DTS)中,要查看每个小时源端产生了多少条数据
【2月更文挑战第32天】在数据传输服务(DTS)中,要查看每个小时源端产生了多少条数据
66 6
|
6月前
|
存储 SQL NoSQL
数据传输DTS同步问题之同步失败如何解决
数据传输服务(DTS)是一项专注于数据迁移和同步的云服务,在使用过程中可能遇到多种问题,本合集精选常见的DTS数据传输问题及其答疑解惑,以助用户顺利实现数据流转。