前前言❤️:本节课的内容及其重要也比较难懂,涉及到了传说中的三次握手和四次挥手的知识,为了避免出现纰漏我也是看了两遍才敢动笔写这篇补充笔记,举例和整理都花了不少时间,希望能对大家有帮助;其次是本节和上一节关系比较密切,建议先彻底搞懂再来看这节课。上节补充笔记:中科大计网学习记录笔记(十五):可靠数据传输的原理。
前言:
学习视频:中科大郑烇、杨坚全套《计算机网络(自顶向下方法 第7版,James F.Kurose,Keith W.Ross)》课程
该视频是B站非常著名的计网学习视频,但相信很多朋友和我一样在听完前面的部分发现信息量过大,有太多无法理解的地方,在我第一次点开的时候也有相同的感受,但经过了一段时间项目的学习,对计网有了更多的了解,所以我准备在这次学习的时候做一些记录并且加入一些我的理解,希望能够帮助到大家。
往期笔记可以看专栏中的内容😊😊😊
💡 TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层协议,用于在网络上可靠地传输数据。
TCP 的报文段就是本层的数据单元 PDU,其由这几个部分构成
字段 | 长度(位) | 描述 |
---|---|---|
源端口号 | 16 | 指明发送端口 |
目的端口号 | 16 | 指明接收端口 |
序列号 | 32 | 标识数据段的顺序 |
确认号 | 32 | 对收到的数据进行确认 |
首部长度 | 4 | 表示 TCP 头部的长度 |
保留 | 6 | 保留字段,未使用,置为 0 |
控制位 | 6 | 标志位,用于控制连接和数据传输 |
窗口大小 | 16 | 接收端 可接收的数据量 |
校验和 | 16 | 用于检测传输过程中的错误 |
紧急指针 | 16 | 指示紧急数据的位置 |
选项和填充 | 可变 | 传输额外的控制信息和填充字节 |
💡
MSS
(最大段大小)是 TCP 协议中的一个参数,用于指示在 TCP 报文段中能够容纳的最大数据量。它表示在不分段的情况下,一个 TCP 报文段能够携带的最大数据量。
TCP 将数据分割成一个一个报文段来发送出去,需要由编号来标识发出去的报文段的顺序。
看一个案例
主机 A 向主机 B 发送一个字符,主机 B 将其回显出来;主机 A 发送标号为 42 的报文,同时请求标号为 79 的报文,B 返回标号为 79 的报文并且返回 ACK 请求标号为 43 的报文。
💡 为什么序号不是从零开始,而是要每次重新约定?
- 通过使用不从0开始的序号,TCP可以更容易地区分新的数据包和之前通信中滞留的数据包。
- TCP序号不是从0开始的主要原因是为了提高安全性和防止攻击。如果序号从0开始,那么攻击者可以通过伪造初始序号来发送欺骗性的数据包或发起拒绝服务攻击。
💡 在TCP报文头部中,控制位是指用来控制TCP连接状态和行为的位。
通过不同的控制位可以指示数据包的类型、状态或要执行的操作。
TCP报文头部的控制位包括以下几个:
💡 TCP 中的超时时间通常是根据网络的往返时间(RTT)来动态设置的。RTT 是数据段从发送到接收并收到确认的时间,它是 TCP 连接中的一个重要指标,反映了数据在网络中传输的延迟。
平滑的往返时间估计值:
E
s
t
i
m
a
t
e
d
R
T
T
=
(
1
−
a
)
∗
E
s
t
i
m
a
t
e
d
R
T
T
+
a
∗
S
a
m
p
l
e
R
T
T
EstimatedRTT = (1- a)*EstimatedRTT + a*SampleRTT
EstimatedRTT=(1−a)∗EstimatedRTT+a∗SampleRTT
- EstimatedRTT 是平滑的往返时间估计值;
- SampleRTTSampleRTT 是每次测量到的往返时间样本值;
- α 是平滑系数,通常取值在0到1之间,用于控制新样本值对于估计的影响程度。
估计出来往返时间的值,利用这个值来估计偏差
D
e
v
R
T
T
=
(
1
−
β
)
×
D
e
v
R
T
T
+
β
×
∣
S
a
m
p
l
e
R
T
T
−
E
s
t
i
m
a
t
e
d
R
T
T
∣
DevRTT=(1−β)×DevRTT+β×∣SampleRTT−EstimatedRTT∣
DevRTT=(1−β)×DevRTT+β×∣SampleRTT−EstimatedRTT∣
最后将超时时间设置为平滑的往返时间 + 四倍的估计偏差,通过这种设置可以降低拥塞。
💡 TCP 提供了可靠的数据传输服务。
🍀 TCP 在 IP 提供的不可靠服务的基础上建立了 RDT(可靠数据传输)。
💡 累计确认:接收端通常会 等待一小段时间(通常是几毫秒)来看是否有其他数据段到达。如果在此等待期间没有其他数据到达,接收端将发送一个 ACK,确认已接收到的数据。如果在等待期间有其他数据到达,接收端可能会将这些数据包含在同一个 ACK 中,从而合并确认消息。
💡 单个重传定时器:TCP 发送方的重传定时器设定在最早发送的那个字段,当超时的时候只是重发这个最早的字段,而不是像 GBN 那样重发全部。
🍀 TCP 发送方通过以下两种事件触发重传机制
💡 优先考虑简化的发送方,即忽略重复的确认和流量控制以及拥塞控制
💡 使用有限状态机(FSM)来描述
- 是一种抽象的计算模型,用于描述系统在不同状态之间的转换以及状态转换所触发的行为。有限状态机由一组状态、一组输入和一组状态转换规则组成。
- 使用圆来表示一种状态,使用连线来表示从一个状态到另一个状态的变迁,连线上的标注:分子表示引起状态变迁的事件,分母表示状态变迁的时候要进行的动作。
上图中标注了发送方 TCP 实体在 收到应用层数据、超时以及收到 ACK 的处理机制。
create segment, seq
),发送的报文段的下一个数据的序列号设置为 NextSeqNum + length(data)
,这就是上面提到的偏移量,比如我本次发送的数据的 seq = 92
发送了 8
个字节的数据,那下次数据的序列号就是 92 + 8 - 1 + 1
也就是 100
,然后启动一个定时器。y
(累计确认,不一定是移动一位),如果现在还有未确认的段,就重新启动定时器,或者所有需要发送的数据已经确认完毕就终止定时器。先明确一点,无论发送方发送什么,接收方的 ACK 总是提出它此时需要的数据。
比如上图中的第二个例子,发送方因为数据过早超时再次发送了 seq = 92
的数据,但此时接收方已经接收到了编号 seq = 120
以前的所有数据,所以此时请求的是 seq = 120
上图描述的是 TCP 接收方的累计确认机制,即其 ACK 中请求的报文,表示这个报文以前的所有报文都已经收到,而不是类似于 SR 协议那样每次收到一个报文都发送一个 ACK。
关于产生 TCP ACK 的建议:
seq = 92
8
个字节,先暂时等待不发,此时又到了一个 seq = 100
20
个字节,此时直接发送 ACK(120)。gap
起点的一部分 gap
,此时也立即发送新的 ACK。💡 最后两条的案例演示
比如说这是接受方的滑动窗口,绿色表示已经接收到的,黄色表示未确认的,当发现乱序的时候立即发送一个 ACK 来请求黄色的部分。
当黄色部分被填补了一部分,此时也是立即发送确认来请求新的黄色块,但如果完全填补就移动窗口到最右端恢复正常的请求顺序。
💡 因为发送方的超时时间设置的比较保守,所以需要有一种机制来提高其效率。
当报文段丢失的时候,会引起多个重复的 ACK
比如这个例子,和上面提到的 TCP ACK 的建议相同,乱序到达的时候接收方会立即发送请求填补空缺的 ACK,即在 40
60
70
80
到达的时候均请求 50
的报文段,当冗余请求累积到三个的时候,发送方会触发快速重传机制,立即 重发 seq = 50
的报文段。
快速重传算法
💡 因为接收方的接收能力是有限的,如果发送方发送的过快会导致数据的溢出,所以发送方要根据接收方的剩余窗口来决定自己发送的数据的总大小。
因为上层读取数据需要时间,所以暂时未读取的数据要存在接收方的缓冲区(buffer)中,这个缓冲区同时也接收发送方发送的数据,剩余的缓冲区就是总缓冲区的大小减去此时缓冲区中的数据大小。
RecvBuffer
大小通过socket
的选项来设置,通常默认的大小为4096
字节。- 很多操作系统会自动的调整
Buffer
发送方得知了接收方的剩余缓冲区大小的时候,保证其发送的字节数 ≤ rwnd
值
💡 关于捎带技术(Piggybacking):
- 捎带技术(Piggybacking)是一种优化网络通信的方法,常见于TCP协议中。
- 它利用已有的数据包来携带额外的信息,而不是单独发送一个新的数据包。
- 发送方在作为数据的发送方的时候,同时也作为 ACK 的接收方
下面来看一个例子
农民 1 卖给农民 2 一群羊,农民 2 寄信来说羊收到了
然后农民 2 再次寄信将钱发给农民 1
💡 那为什么不直接寄信说羊收到的时候就将钱寄过去呢?
- 这就是捎带技术,利用已有的数据包来携带额外的信息,而不是单独发送一个新的数据包。
💡 接收方维护两个数据来实现剩余 buffer 的计算
💡 三次握手就是客户端发送连接请求,服务器发送同意连接的请求,客户端再次发送确认请求,来表示 客户端是活跃的。
💡 两次握手导致的问题是由于连接是单方维护的,只是由服务器去维护连接资源,而客户端不去维护,这就导致了双方状态的不对等,三次握手通过在连接建立的过程中引入客户端的确认,解决了这个问题,使连接状态在客户端和服务器之间得到了正确的同步。
💡 拒绝服务(Denial of Service,DoS)攻击是一种旨在使目标系统或网络资源无法提供正常服务的恶意行为。攻击者通过不断发送大量的请求或者恶意数据包,耗尽目标系统的资源(如带宽、处理能力、内存或存储空间),导致正常用户无法访问或使用该系统或网络资源。
💡 四次挥手确保了双方都能够安全地关闭连接,同时允许双方在关闭连接之前完成他们的数据传输;三次握手四次挥手都是为了保证双方的状态统一,即一方达到某一状态之前需要告知另一方,需要收到对方的 ACK。在建立连接时,三次握手确保了双方都已准备好通信;在关闭连接时,四次挥手确保了双方都能够安全地完成数据传输并关闭连接,避免了半开连接状态和潜在的数据丢失问题。