一、TCP基础知识
1.1 TCP和UDP的区别?
TCP
是面向连接的协议,在收发数据前必须和对方建立可靠的连接,建立连接的3
次握手、断开连接的4
次挥手,为数据传输打下可靠基础;
UDP
是无连接的,不可靠传输,尽最大努力交付数据,协议简单、资源要求少、传输速度快、实时性高的特点,适用于对传输效率要求高,但准确率要求低的应用场景,比如域名转换(DNS
)、远程文件服务器(NFS
)等。
1.2 TCP 为什么需要三次握手?为什么需要四次挥手?如何保证可靠?
为什么需要三次握手?
三次握手能确保双发的收发能力(确定双通道通畅)是OK。
为什么需要四次挥手
因为TCP
是全双工协议,双方都可以发送和接收数据。当一方决定终止连接时,另一方可能还有数据需要发送。
如何保证可靠?
- 错误检测:
TCP
使用校验和功能来检测数据包在传输过程中是否出现错误。 - 顺序保证:
TCP
给每个数据包分配序号,接收方将数据包按序号重组,确保有序传输。 - 重传:如果接收方在一定时间内未对发送方的数据包进行确认,发送方将重传该数据包。
- 流量控制:发送方和接收方通过交换窗口大小协商数据传输速率,以避免传输过快导致的缓冲区溢出。
- 拥塞控制:
TCP
使用各种算法来监测网络拥塞情况,并相应地调整数据发送速率。
1.3 TCP如何保证包的顺序传输?
序号传输,到接收方的缓存区以后会按序号重排。
1.4 TCP超时重传?
原理是在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的ACK
报文,那么就重新发送数据,直到发送成功为止。
RTO
(Retransmission Timeout
)是TCP
协议中用于设置重传定时器的超时时间。计算RTO
的方法需要权衡:(1)设置合理的超时时间以避免过早重传,浪费带宽和资源;(2)又要确保能在适当的时间内检测到丢失的数据包并进行重传。
RTO
的计算主要依赖于以下指标:
RTT
(Round-Trip Time
):指数据包从发送方到接收方,以及ACK
从接收方回到发送方所需的时间。网络条件、延迟和拥塞会影响RTT
的变化。SRTT
(Smoothed Round-Trip Time
):平滑RTT
,是基于连续RTT
测量值的加权平均值,用于估算当前的RTT
。RTTVAR
(Round-Trip Time Variation
):RTT
的变化量,用于描述RTT
的不稳定程度。
1.5 TCP流量控制?
TCP
流量控制(Flow Control
)是一种控制数据发送速率的机制,避免发送方发送过快导致接收方的缓冲区溢出。流量控制通过「滑动窗口」(Sliding Window
)实现,它可以根据接收方处理能力和网络状况动态调整发送速率。
以下是TCP
流量控制的主要步骤:
接收方设置窗口大小:接收方根据其接收缓冲区可用空间设置一个窗口大小。窗口大小表示接收方允许发送方连续发送数据包的最大数量,不必等待每个数据包的确认。这个窗口大小值会在
ACK
数据包的TCP
头部字段中反馈给发送方。发送方基于窗口大小调整发送速率:发送方根据接收到的窗口大小信息调整其发送速率。发送方会跟踪已发送但尚未被确认的数据包的数量,确保在接收到
ACK
前不至于超过接收方的窗口大小。滑动窗口:随着发送方接收到
ACK
,它将更新已发送但未确认的数据包数量。然后根据未确认数据包数量继续发送新的数据包,同时保持发送速率不超过接收方的窗口大小。这种动态调整发送速率的过程像一个滑动窗口一样。窗口大小调整:在数据传输过程中,接收方根据其接收缓冲区的剩余容量不断更新窗口大小。接收方通过
ACK
数据包将新的窗口大小发送给发送方。如果接收方的缓冲区已满,窗口大小将被设置为0
,发送方会暂停发送数据,直到接收到有效窗口大小。
通过滑动窗口的流量控制机制,TCP
协议可以在不同的网络环境下实现稳定、高效的数据传输。同时,流量控制也能确保接收方及时处理数据包,防止缓冲区溢出。
1.6 TCP 拥塞控制?
TCP
拥塞控制(Congestion Control
)是一种动态调整数据发送速率的机制,目的是减少因网络拥塞造成的数据包丢失、重传和延迟。拥塞控制与流量控制相互补充,共同保证了TCP
数据传输的可靠性和有效性。TCP
拥塞控制主要依赖以下四个算法:
慢开始(Slow Start): 该算法用于拥塞窗口(
cwnd
)的初始阶段,通过逐渐增大拥塞窗口来寻找可接受的发送速率。发送方以设置为1 MTU
(最大传输单元)的初始拥塞窗口大小开始发送数据,并在每次收到ACK
时将拥塞窗口大小加倍。慢开始会在拥塞窗口达到预设的门限(ssthresh
)或出现丢包现象时结束。拥塞避免(Congestion Avoidance): 当拥塞窗口达到门限,拥塞避免算法启动,以减缓窗口增长速率。在此阶段,拥塞窗口以加法增长,即每次收到一个
ACK
时,发送方会将拥塞窗口加上一个较小的固定值。这样,在网络达到饱和时,拥塞避免算法可以避免进一步加剧拥塞。快速重传(Fast Retransmit): 该算法用于在无需等待
RTO
超时的情况下快速检测和重传丢失的数据包。当发送方连续收到三个具有相同ACK
序号的ACK
数据包时,快速重传算法启动,立即发送丢失的数据包。快速恢复(Fast Recovery): 快速恢复算法在快速重传后启动,旨在在短时间内恢复慢开始门限和拥塞窗口。发送方会将门限设为其当前拥塞窗口的一半,并进入拥塞避免阶段,从而在正确调整拥塞窗口的同时避免重新回到慢开始阶段。
通过这四种拥塞控制算法,TCP
协议可以动态调整发送速率,适应不同的网络状况,减小拥塞,降低数据包丢失或延迟,从而提高数据传输效率。
1.7 释放连接时为什么TIME-WAIT状态必须等待2MSL时间?
在TCP
连接释放过程中,当某个端点收到对方发送的FIN
数据包并发送ACK
确认后,TCP
会进入TIME-WAIT
状态。TIME-WAIT
状态持续时间通常为2MSL
(MSL
是最长段生存时间,Maximum Segment Lifetime
),这样设置的主要原因有两个:
确保最后一个 ACK 数据包正确传送: 当端点收到
FIN
数据包并发送ACK
时,可能会因为网络原因造成ACK
丢失,使对方无法知晓。在2MSL
的等待期间,对方的重传定时器可能触发,重新发送FIN
数据包。端点在TIME-WAIT
状态可以重新发送ACK
数据包,以确保对方收到,从而正常关闭连接。防止旧的数据包在新连接中传播: 进入
TIME-WAIT
状态后,端点会暂停一段时间再创建新的连接。这段时间内,旧连接的所有数据包都会因超过MSL
而丢弃。设置为2
倍MSL
的时间可以确保旧连接产生的数据包在新连接创建之前已经被废弃并从网络中消散,降低出现错误的可能性。
等待2MSL
时间是TCP
协议为保证数据包可靠传输和避免潜在错误设定的一种安全机制。通过这种机制,TCP
可以有效防止数据包的错误传播,确保连接的正确关闭。
1.8 TCP常用的几种定时器
TCP
协议中有以下四种常见的定时器,用于控制数据传输过程中的不同阶段和事件:
重传定时器(Retransmission Timer): 重传定时器用于检测数据包发送后是否在合理的时间内收到确认
ACK
,从而判断发送的数据包是否成功传达。如果在定时器超时前没有收到ACK
,TCP
端点会认为数据包已丢失并触发超时重传,重发该数据包。该定时器的超时时间取决于RTO
(Retransmission Timeout
),可以通过RTT
(往返时间)测量值来动态调整。确认延迟(Delayed ACK)定时器: 为了提高网络传输效率,接收端通常不会对每个收到的数据包立即发送
ACK
。确认延迟定时器可以设置一个间隔时间内允许接收端批量发送确认ACK
,减小网络负载。如果此定时器超时或连续收到相同序号的段,则接收端需要立即发送ACK
。持续定时器(Persistence Timer):
TCP
会根据接收方的窗口大小(Window Size
)限制发送速率,防止接收缓冲区溢出。当接收方窗口大小为0
时,发送方会停止发送数据。持续定时器用于在这种情况下周期性查询接收方窗口是否可用。定时器超时后,发送方会发送一个窗口探测数据包(Window Probe
),监测接收方是否具有新的窗口大小。TIME-WAIT 定时器: 在
TCP
释放连接的过程中,某个端点收到对方的FIN
数据包并发送确认ACK
后,会进入TIME-WAIT
状态。TIME-WAIT
定时器的作用是持续时间通常为2MSL
(MSL
是最长段生存时间,Maximum Segment Lifetime
)。在此期间,端点确保最后一个ACK
数据包正确传输,并防止旧数据包在新连接中传播。保活计时器:保活计时器使用在某些实现中,用来防止在两个
TCP
之间的连接出现长时间的空闲。假定客户打开了到服务器的连接,传送了一些数据,然后就保持静默了。也许这个客户出故障了。在这种情况下,这个连接将永远的处理打开状态。要解决这种问题,在大多数的实现中都是使服务器设置保活计时器。每当服务器收到客户的信息,就将计时器复位。通常设置为两小时。若服务器过了两小时还没有收到客户的信息,他就发送探测报文段。若发送了10
个探测报文段(每一个像个75
秒)还没有响应,就假定客户除了故障,因而就终止了该连接。这种连接的断开当然不会使用四次握手,而是直接硬性的中断和客户端的TCP
连接。
这些定时器通过控制和调整TCP
数据包的发送和接收,对TCP
数据传输过程中的稳定性、可靠性和有效性起到关键作用。
1.9 什么是 TCP BBR
TCP BBR
(Bottleneck Bandwidth and RTT
)是一种拥塞控制算法,旨在改善网络传输的性能。TCP BBR
是由 Google
提出并开发的,其主要目的是为了解决传统拥塞控制算法(如TCP Cubic
和TCP Reno
)在面对高延时、高带宽网络环境时的性能瓶颈和慢启动问题。
TCP BBR
算法基于现实网络条件来进行拥塞控制,主要关注两个关键指标:
Bottleneck Bandwidth(瓶颈带宽):
BBR
估计当下可用的网络带宽,以便在确保效率的同时避免过度拥塞。这样可以确保TCP
流量不会因填满队列而延长延迟。Round-Trip Time (RTT):
BBR
需要估算网络的往返时间(RTT
),以便对通信过程中的延时有个清晰的了解。这有助于BBR
高效地利用网络资源,减小延迟,提升吞吐量。
TCP BBR
通过估算这两个指标来持续适应并优化数据包发送速率,防止过度拥塞或延迟。BBR
主要通过以下两个阶段实现其目标:
Startup 阶段: 在启动阶段,
BBR
加快发送速率,试图尽快找到网络的瓶颈带宽。然后在到达可用带宽上限时稳定发送速率,避免过度占用带宽。Probe and Decide 阶段: 在此阶段,
BBR
定期探测网络带宽和延迟的变化,并根据观察到的信息调整发送速率。这样BBR
能在保持高吞吐量的同时,适应网络环境的变化。
与传统的拥塞控制算法相比,TCP BBR
能更有效地利用网络带宽,降低网络延迟,在具有丢包、高延迟和带宽共享的网络环境中获得更好的性能。多数Linux
发行版支持BBR
,可以通过内核参数配置启用。在云服务、内容分发网络和大型数据中心等应用场景中,TCP BBR
可发挥重要作用。
1.10 TCP连接的建立和断开过程会受哪些配置项的影响?
1.11 TCP 数据发送和接收过程受到什么影响?
1.12 TCP 状态转移
1.13 TCP SO_LINGER
1.14 TCP 糊涂窗口综合征
二、其他基础
2.1 什么是MTU?
MTU
(Maximum Transmission Unit
,最大传输单元)是指在网络传输过程中,一个数据包允许携带的最大数据量。这个值通常取决于底层网络层(如IP
层)和链路层(如 Ethernet
)的约束。MTU
的大小对网络传输效率和延迟有很大影响。
不同类型的网络可能有不同的MTU
值。例如,在Ethernet
中,默认的MTU
值为1500
字节。IP
数据包中包含IP
头部信息(通常为20
字节)和传输层数据(如TCP
数据)。因此,在Ethernet
中,TCP
数据包可携带最大的数据量是1500
字节减去IP
和TCP
头部信息的大小。
在数据传输过程中,如果网络路径上的某个链路的MTU
值较小,可能导致数据包太大而无法传输。在这种情况下,通常需要对大包进行分片(Fragmentation
),将大包切分为多个小包进行发送。然而,分片可能会导致网络传输效率降低,因为每个分片可能需要单独处理和重传。Path MTU Discovery
是一种用于在网络路径中找到最小MTU
值的技术,它可以帮助减少分片,提高网络传输效率。
2.2 什么是 Path MTU Discovery?
Path MTU Discovery
(PMTUD
,路径最大传输单元发现)是一种在IP
层查找两个端点之间的路径最小MTU
值的技术。PMTUD
的目的是选择最合适的数据包大小与网络路径相匹配,从而避免不必要的分片和拥塞,提高传输效率。
PMTUD
的基本工作原理如下:
设置原始数据包大小:发送方首先将数据包的大小设置为其本地
MTU
值。通常情况下,网络层(如IP
层)会遵循“不分片”(Do not Fragment,DF
)标识,不允许对数据包进行分片。发送数据包:发送方将数据包发送到网络中。当数据包在网络路径中经过不同类型的链路时,可能会遇到较小的
MTU
值。接收 ICMP 错误消息:如果路径中的某个链路的
MTU
值大于数据包大小,路由器会抛弃该数据包(由于设置了DF
标识,阻止分片过程)。同时,路由器将发送一个ICMP
错误消息(“需要分片,但DF
标志已设置”)给发送方。该ICMP
消息包含了产生错误的链路的MTU
值。重新调整数据包大小:当发送方收到
ICMP
错误消息后,它会根据ICMP
消息提供的MTU
值重新调整数据包大小。然后,发送方使用新的数据包大小重发数据包。查找路径 MTU:发送方持续沿着路径更新数据包大小,直到数据包成功抵达接收方而不产生
ICMP
错误消息。这个过程可以持续进行,以便在路径MTU
发生变化时实时更新数据包大小。
通过执行Path MTU Discovery
,TCP/IP
可以实现在网络路径中自适应地调整数据包大小,避免分片和降低传输延迟,从而提高网络性能。
2.3 Path MTU Discovery 是这个是什么时候会触发?
Path MTU Discovery
(PMTUD
)通常是在TCP
连接建立阶段开始启动的,并在整个连接过程中持续运作。以下是触发进行PMTUD
的主要时机和条件:
TCP 连接建立阶段: 发送方会在连接建立阶段启动
Path MTU Discovery
。它通过将数据包的“不分片”(Do not Fragment,DF
)标识设置为1
,来阻止对数据包进行分片。初始数据包(如SYN
数据包)的大小基于发送方的本地MTU
值。连接过程中的数据传输: 在
TCP
数据传输过程中,发送方会持续使用之前发现的路径MTU
。如果路径发生变化或网络条件调整,导致MTU
值更新,发送方会通过ICMP
错误消息的接收实时更新路径 MTU。收到 ICMP 错误消息: 如果数据包的大小大于路径中某个链路的 MTU 值,那么路由器会抛弃该数据包,并向发送方发送 ICMP 错误消息(“需要分片,但 DF 标志已设置”)。发送方在收到此类 ICMP 错误消息时,会触发 Path MTU Discovery,根据从 ICMP 消息中获取的新的 MTU 值,重新调整数据包大小。
TCP 保活保持定时器(optional): 在一些实现中,TCP 连接可能会在长时间空闲后产生保活保持数据包(Keep-alive Probes)。如果启用此功能,保活保持数据包也可以用于触发 Path MTU Discovery,以确定路径 MTU 在空闲期间是否发生变化。
总之,Path MTU Discovery
在TCP
连接的整个生命周期中都可能触发,主要时机包括连接建立阶段、连接过程中的数据传输和收到ICMP
错误消息。这种动态探测机制确保了网络传输性能的优化和资源的充分利用。
2.4 什么是MSS?
MSS
(Maximum Segment Size
,最大段大小)是TCP
数据包在网络传输过程中,载荷(即TCP
数据段)的最大字节数。MSS
并不包括TCP
头和IP
头部信息的大小。MSS
的大小主要取决于网络的MTU
(Maximum Transmission Unit
,最大传输单元)值。
为了确保TCP
数据包能够顺利在不同类型的链路上传输,避免分片和端点重新组合所带来的性能损失,MSS
常常是根据网络路径MTU
减去IP
头部和TCP
头部信息的大小计算得出的。
例如,在传统的Ethernet
网络环境中,MTU
默认值为1500
字节。因为IP
头部的大小通常为20
字节,TCP
头部的大小也通常为20
字节,所以典型情况下,MSS
的值为1500 - 20(IP头部) - 20(TCP头部) = 1460 字节
。
MSS
值在TCP
连接建立过程中(三次握手阶段)由双方实际最大段大小的取小值决定。客户端和服务器分别在发起连接(SYN
)和确认连接(SYN-ACK
)的数据包中,通过MSS
选项来通知对方自己的最大段大小。通过协商获得的MSS
值可以在后续数据传输过程中避免分片,提高网络传输效率。
2.5 IP分片、TCP分组?
1. IP 分片:
当IP
层的数据包大小超过当前网络链路的MTU
(最大传输单元)时,会触发IP
分片。IP
分片是在网络层将大数据包拆分为若干个较小的数据包,使其大小适应网络链路的MTU
,以便顺利传输。 分片后的数据包在网络层(IP
层)重新组装,以还原原始大数据包。
IP分片主要是为UDP服务的:
2. TCP 分组:
TCP
分组发生在传输层,主要是为了根据接收方拥有的空闲缓冲区大小(窗口大小)和 MSS
(最大段大小)将数据流划分为合适大小的数据段。
当本地应用程序向TCP
层传输大量数据时,TCP
层为了遵循MSS
值和接收方窗口大小的限制,会将数据拆分成较小的数据段,然后将这些段加上TCP
头部分装成数据包。对于接收方而言,TCP
层收到数据包后,会将数据包的数据部分提取出来,再将其串联成数据流,并传递给接收方应用程序。
总结:IP
分片发生在网络层,主要是为了适应不同网络链路的MTU
限制。TCP
分组发生在传输层,是为了将数据流拆分成合适大小的数据段,以满足接收方窗口大小和MSS
限制。在实际网络传输过程中,数据包可能会经历IP
分片、TCP
分组或二者的结合。
2.6 Delay ack、 Nagle算法?
1. Delayed ACK(延迟确认):
Delayed ACK
是一种TCP
确认策略,用于减小频繁发送小数据包的ACK
(确认)带来的网络开销。在这种策略下,TCP
接收方在收到数据包后,并不立即发送ACK
,而是等待一段时间(通常为100-200
毫秒),期间如果接收方有需要发送的数据,则将ACK
与数据一并发送。这样可以有效地降低ACK
数据包在网络中的传输数量,提高网络利用率。
但是,如果在延迟时间内没有接收到新的数据,则ACK
会按照设置的超时时间被发送出去,以确保发送方能够及时得到确认信息,避免无谓的重传。
2. Nagle 算法:
Nagle
算法是一种TCP
流量控制策略,用于减少小数据包在网络中的传输, 从而避免网络拥塞。Nagle
算法通过合并多个正在等待确认的小数据包,并将它们组装成一个较大的数据包一起发送。
Nagle
算法的核心逻辑如下:
a. 如果发送方的发送缓冲区中有未确认的小数据包(即已发送但尚未收到ACK
的数据包),则将新生成的小数据包放在发送缓冲区中等待。
b. 如果接收到一个ACK
(对之前发送缓冲区内的数据包的确认),Nagle
算法会将缓冲区中的所有小数据包合并为一个新的数据包一起发送。
c. 如果发送缓冲区已满或者达到MSS
(最大段大小),则直接发送。
Nagle
算法与Delayed ACK
都有助于降低小数据包的数量,从而减少网络拥塞和提高网络传输效率。然而,在某些需要低延迟和高实时性的应用场景(如实时游戏、音视频通话等)下,它们可能会影响传输性能。因此,可以根据实际应用需求决定是否启用这两个算法。
2.7 数据包经过路由器,哪些字段可能会被修改。
IP
层TTL
(Time To Live
):每经过一个路由器,TTL
的值会减1
,以防止数据包在网络中无限循环。当TTL
减至0
时,路由器会丢弃该数据包,并可能发送一个ICMP
差错报文通知发送方。- 校验和(
Header Checksum
):TTL
的改变会导致IP
头部的校验和发生变化。路由器需要重新计算并更新校验和字段,以确保数据包在接收端被正确解析。 - 源
IP
地址和目标IP
地址:在某些特殊情况下,如使用NAT
(网络地址转换)技术时,路由器可能需要修改源IP
地址和/或目标IP
地址。
- 链路层
- 源
MAC
地址和目标MAC
地址:路由器在转发数据包时,需要将源MAC
地址改为自身的MAC
地址,并将目标MAC
地址改为下一个跳点(下一个路由器或者最终目的主机)的MAC
地址。
- 源
2.8 IP 部首 20 个字节
4字节: 4位版本、4位首部长度、8位服务类型、 16位总长度(65 536)
- 版本4位,表示版本号,目前最广泛的是4=B1000,即常说的IPv4;相信IPv6以后会广泛应用,它能给世界上每个纽扣都分配一个IP地址。 一般是 0100 表示IPV4
- 头长4位,数据包头部长度。它表示数据包头部包括多少个32位长整型,也就是多少个4字节的数据。无选项则为5(红色部分)。 一般是 0101 表示 5*4=20个
- 服务类型,包括8个二进制位,一般全部都是0,大多数的TCP/IP以忽略
- 包裹总长16位,当前数据包的总长度,单位是字节。当然最大只能是65535,及64KB。 (这个是除了以太网部首长度以后的包长度,加上以太网部首等于整个长度)
4字节 : 16位重组标示、3位标志、13位偏移
- 重组标识16位,发送主机赋予的标识,以便接收方进行分片重组。 通常每发一个报文就会加1
- 标志3位,他们各自的意义如下:
保留段位(2):1位,未使用 0… …. …. …. = Reserved bit: Not set
不分段位(1):1位,.1.. …. …. …. = Don’t fragment: Set TCP都是1
更多段位(0):1位,..0. …. …. …. = More fragments: Not set 是否有更多数据包, - 段偏移量13位,与更多段位组合,帮助接收方组合分段的报文,以字节为单位。…0 0000 0000 0000 = Fragment offset: 0 当前分片的索引书
4字节 :1字节TTL、1字节协议代码、2字节头部校验
- 生存时间8位,经常ping命令看到的TTL(Time To Live)就是这个,每经过一个路由器,该值就减一,到零丢弃。
- 协议代码8位,表明使用该包裹的上层协议,如ICMP=1,IGMP =2,TCP=6,UDP=17等。
- 头检验和16位,是IPv4数据包头部的校验和。
4字节 源IP地址
4字节 目的IP地址
2.9 TCP 部首 20 个字节
- 4字节 :2字节源端口号,2字节目的端口号
- 4字节:包序列号 Sequence number: 1 (relative sequence number)
- 4字节:Ack序列号 Acknowledgment number: 5 (relative ack number)
- 4字节 4位首部长度、保留6位、6个标志位,16位窗口大小
- 4-1.偏移4位,类似IP,表明数据距包头有多少个32位。 0101 …. = Header Length: 20 bytes (5)
- 4-2.保留6位,未使用,应置零。
000. .... .... = Reserved: Not set ...0 .... .... = Nonce: Not set .... 0... .... = Congestion Window Reduced (CWR): Not set cwnd .... .0.. .... = ECN-Echo: Not set * 通告接收窗口(rwnd):预防应用程序发送的数据超过对方的缓冲区,接收方使用的流量控制。 * 拥塞窗口(cwnd):预防应用程序发送的数据超过了网络所能承载的能力。发送方使用的流量控制。 * 发送窗口:就是指上面两者的较小值
- 4-3.紧急比特URG—当URG=1时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。…. ..0. …. = Urgent: Not set
- 4-4.确认比特ACK—只有当ACK=1时确认号字段才有效。当ACK=0时,确认号无效。…. …1 …. = Acknowledgment: Set
- 4-5 …. …. 0… = Push: Not set PSH为1的情况,一般只出现在 DATA内容不为0的包中,也就是说PSH为1表示的是有真正的TCP数据包内容被传递。
- 4-6.复位比特RST(Reset) —当RST=1时,表明TCP连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。…. …. .0.. = Reset: Not set
- 4-7.同步比特SYN—同步比特SYN置为1,就表示这是一个连接请求或连接接受报文。…. …. ..0. = Syn: Not set
- 4-8.终止比特FIN(FINal)—用来释放一个连接。当FIN=1时,表明此报文段的发送端的数据已发送完毕,并要求释放运输连接。…. …. …0 = Fin: Not set
- 4-9.窗口字段16位,窗口字段用来控制对方发送的数据量,单位为字节。TCP连接的一端根据设置的缓存空间大小确定自己的接收窗口大小,然后通知对方以确定对方的发送窗口的上限。Window size value: 908
- 4字节:2字节校验和、2字节紧急指针
- 5-1 校验和:源机器基于数据内容计算一个数值,收信息机要与源机器数值 结果完全一样,从而证明数据的有效性。检验和覆盖了整个的TCP报文段:这是一个强制性的字段,一定是由发送端计算和存储,并由接收端进行验证的。Checksum: 0xf3d2 [unverified]
- 5-2 紧急指针:是一个正偏移量,与序号字段中的值相加表示紧急数据最后一个字节的序号。TCP的紧急方式是发送端向另一端发送紧急数据的一种方式 Urgent pointer: 0
2.10 UDP 首部 8 字节
- 4字节 :2字节源端口号,2字节目的端口号
- 4字节 :2字节UDP包长度,2字节UDP校验和
三、其他
3.1 浏览器访问一个网址,经历了哪些过程?
在浏览器中输入
www.example.com
域名,操作系统会先检查自己本地的hosts
文件是否有这个网址映射关系,如果有,就先调用这个IP
地址映射,完成域名解析。如果
hosts
里没有这个域名的映射,则查找本地DNS
解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析。如果
hosts
与本地DNS
解析器缓存都没有相应的网址映射关系,首先会找TCP/IP
参数中设置的首选DNS服务器,在此我们叫它本地DNS
服务器,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。如果要查询的域名,不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个
IP
地址映射,完成域名解析,此解析不具有权威性。如果本地
DNS
服务器本地区域文件与缓存解析都失效,则根据本地DNS
服务器的设置(是否设置转发器)进行查询,如果未用转发模式,本地DNS
就把请求发至13
台根DNS
,根DNS
服务器收到请求后会判断这个域名(.com
)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP
。本地DNS
服务器收到IP
信息后,将会联系负责.com
域的这台服务器。这台负责.com
域的服务器收到请求后,如果自己无法解析,它就会找一个管理.com
域的下一级DNS
服务器地址(http://www.example.com
)给本地DNS
服务器。当本地DNS
服务器收到这个地址后,就会找http://www.example.com
域服务器,重复上面的动作,进行查询,直至找到www.example.com
主机。如果用的是转发模式,此
DNS
服务器就会把请求转发至上一级DNS
服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根DNS
或把转请求转至上上级,以此循环。不管是本地DNS
服务器用是是转发,还是根提示,最后都是把结果返回给本地DNS
服务器,由此DNS
服务器再返回给客户机。
3.2 https 加密过程?
HTTPS
协议是HTTP
协议的安全版本,它在HTTP
和TCP
之间增加了一个安全层(SSL
或TLS
),用于在数据传输过程中提供加密、完整性和认证。HTTPS
加密过程主要在SSL/TLS
握手阶段完成,以下是简化的加密过程:
客户端发起握手请求: 当浏览器要访问
HTTPS
网站时,首先会向服务器发送一个Client Hello
消息。这个消息中包含客户端支持的SSL/TLS
版本、支持的加密算法(如:AES、RSA、SHA
等)、支持的压缩方法以及一个随机数。服务器回应握手: 服务器收到客户端的请求后,会从中选择自己支持的最高
SSL/TLS
版本、加密算法和压缩方法,并发送一个Server Hello
消息给客户端。此消息中包含选定的SSL/TLS
版本、加密算法和压缩方法,以及一个随机数。服务器还会将其公钥证书(包含公钥)发送给客户端。验证证书: 客户端收到服务器的证书后,会首先验证证书的有效性和合法性。通常,这涉及验证证书的颁发机构、签名和过期时间等信息。如果证书验证失败,客户端会发出安全警告,让用户决定是否继续访问。
生成预主密钥和主密钥: 验证证书后,客户端会生成一个新的随机数(预主密钥),然后使用服务器的公钥加密预主密钥,并将其发送给服务器。接着,客户端和服务器利用之前交换的三个随机数(客户端随机数、服务器随机数和预主密钥)通过预定的算法生成主密钥。值得注意的是,由于客户端和服务器都持有这三个随机数和加密算法,因此可以独立地计算出相同的主密钥。
发送”Finished”消息: 服务器和客户端均完成主密钥的计算后,它们会互相发送
Finished
消息(由主密钥加密),以确认SSL/TLS
连接已经建立。从此以后,双方之间的所有通信都使用这个主密钥进行加密和解密。数据传输: 握手完成后,客户端与服务器之间的数据传输将使用主密钥进行加密,确保数据的机密性、完整性和安全性。
双向TLS
:
3.3 证书签名和验签
3.4 服务端网络IO线程模型
一、Thread Per Connection
采用阻塞式 I/O 模型获取输入数据;
每个连接都需要独立的线程完成数据输入,业务处理,数据返回的完整操作。
缺点:
当并发数较大时,需要创建大量线程来处理连接,系统资源占用较大;
连接建立后,如果当前线程暂时没有数据可读,则线程就阻塞在 Read 操作上,造成线程资源浪费。
二、单Reactor单线程
优点:简单,没有多线程,没有进程通信
缺点:性能,无法发挥多核的极致,一个handler卡死,导致当前进程无法使用,IO和CPU不匹配
场景:客户端有限,业务处理快,比如redis
三、单Reactor多线程
优点:充分利用的CPU
缺点:进程通信,复杂,Reactor承放了太多业务,高并发下可能成为性能瓶颈
四、主从Reactor多线程
主Reactor负责建立连接,建立连接后的句柄丢给子Reactor,子Reactor负责监听所有事件进行处理
优点:职责明确,分摊压力
Nginx/netty/memcached都是使用的这
五、Proactor 模型(异步IO)
编程复杂性,由于异步操作流程的事件的初始化和事件完成在时间和空间上都是相互分离的,因此开发异步应用程序更加复杂。应用程序还可能因为反向的流控而变得更加难以 Debug;
内存使用,缓冲区在读或写操作的时间段内必须保持住,可能造成持续的不确定性,并且每个并发操作都要求有独立的缓存,相比 Reactor 模式,在 Socket 已经准备好读或写前,是不要求开辟缓存的;
操作系统支持,Windows 下通过 IOCP 实现了真正的异步 I/O,而在 Linux 系统下,Linux 2.6 才引入,目前异步 I/O 还不完善。
3.5 Syn攻击原理与防护措施攻击。什么是半连接队列。
SYN
攻击(即TCP SYN Flood
攻击)是一种常见的拒绝服务(DoS
)攻击手段。其基本原理是利用TCP
三次握手机制的漏洞向目标服务器发送大量伪造的SYN
数据包。攻击者在发送SYN
数据包后,不会发送预期的ACK
数据包来完成三次握手,从而导致目标服务器维护大量未完成的连接,消耗其资源。当服务器的资源耗尽时,正常的新连接请求将无法处理,导致服务瘫痪。
SYN
攻击防护措施:
- 增加半连接队列容量: 调整系统参数以增加半连接队列的容量,使其能够容纳更多的半连接,从而降低由
SYN
攻击导致的服务丢失风险。 - 减小
SYN
超时时间: 缩短等待客户端ACK
回复的超时时间,使系统能在短时间内回收未被利用的半连接资源。 - 开启
SYN Cookie
机制: 启用SYN Cookie
功能后,服务器无需为每个SYN
连接分配半连接资源。当收到一个SYN
数据包时,服务器会生成一个特殊的Cookie
,并将其包含在SYN+ACK
数据包中发送给客户端。收到最后的ACK
数据包时,服务器根据Cookie
可恢复原始信息。例如,Linux
内核中提供的net.ipv4.tcp_syncookies
参数可启用SYN Cookie
功能。
如何知道应用程序的 TCP 全连接队列大小?
在服务端可以使用ss
命令,来查看TCP
全连接队列的情况:
ss -ltn
全连接队列满了,就只会丢弃连接吗?
tcp_abort_on_overflow
共有两个值分别是0
和1
,其分别表示:
0
:表示如果全连接队列满了,那么server
扔掉client
发过来的ack
;1
:表示如果全连接队列满了,那么server
发送一个reset
包给client
,表示废掉这个握手过程和这个连接;
如何增大 TCP 全连接队列呢?
TCP
全连接队列足最大值取决于somaxconn
和backlog
之间的最小值,也就是min(somaxconn, backlog)
如何查看 TCP 半连接队列长度?
很遗憾,TCP
半连接队列长度的长度,没有像全连接队列那样可以用ss
命令查看。
但是我们可以抓住TCP
半连接的特点,就是服务端处于SYN_RECV
状态的TCP
连接,就是在TCP
半连接队列。
如何模拟 TCP 半连接队列溢出场景?
模拟TCP
半连接溢出场景不难,实际上就是对服务端一直发送TCP SYN
包,但是不回第三次握手ACK
,这样就会使得服务端有大量的处于SYN_RECV
状态的TCP
连接。
建链过程中数据包会被丢弃的几种场景
- 如果半连接队列满了,并且没有开启
tcp_syncookies
,则会丢弃; - 若全连接队列满了,且没有重传
SYN+ACK
包的连接请求多于1
个,则会丢弃; - 如果没有开启
tcp_syncookies
,并且max_syn_backlog
减去当前半连接队列长度小于 (max_syn_backlog >> 2
),则会丢弃;
半连接大小由什么决定的?
在Linux 2.6.32
内核版本,它们之间的关系,总体可以概况为:
- 当
max_syn_backlog > min(somaxconn, backlog)
时, 半连接队列最大值max_qlen_log = min(somaxconn, backlog) * 2
; - 当
max_syn_backlog < min(somaxconn, backlog)
时, 半连接队列最大值max_qlen_log = max_syn_backlog * 2
;
3.6 Http1.0、Http2.0、Http3.0 区别
HTTP 1.0 和 HTTP 1.1 的一些区别
- 缓存处理,在
HTTP 1.0
中主要使用header
里的If-Modified-Since
,Expires
来做为缓存判断的标准,HTTP 1.1
则引入了更多的缓存控制策略例如Entity tag
,If-Unmodified-Since
,If-Match
,If-None-Match
等更多可供选择的缓存头来控制缓存策略。 - 带宽优化及网络连接的使用,
HTTP 1.0
中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP 1.1
则在请求头引入了range
头域,它允许只请求资源的某个部分,即返回码是206(Partial Content)
,这样就方便了开发者自由的选择以便于充分利用带宽和连接。 - 错误通知的管理,在
HTTP 1.1
中新增了24
个错误状态响应码,如409(Conflict)
表示请求的资源与资源的当前状态发生冲突;410(Gone)
表示服务器上的某个资源被永久性的删除。 Host
头处理,在HTTP 1.0
中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname
)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers
),并且它们共享一个IP
地址。HTTP 1.1
的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host
头域会报告一个错误(400 Bad Request
)。- 长连接,
HTTP 1.1
支持长连接(PersistentConnection
)和请求 - 流水线(
Pipelining
)处理,在一个TCP
连接上可以传送多个HTTP
请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP 1.1
中默认开启Connection:keep-alive
,一定程度上弥补了HTTP 1.0
每次请求都要创建连接的缺点。
HTTP 2.0
- 二进制分帧层 (
Binary Framing Layer
),帧是数据传输的最小单位,每个帧都有不同的类型和用途,规范中定义了10
种不同的帧。例如,报头(HEADERS
)和数据(DATA
)帧组成了基本的HTTP
请求和响应;其他帧例如设置(SETTINGS
),窗口更新(WINDOW_UPDATE
), 和推送承诺(PUSH_PROMISE
)是用来实现HTTP/2
的其他功能。那些请求和响应的帧数据通过流来进行数据交换。新的二进制格式是流量控制、优先级、server push
等功能的基础 - 多路复用:也就是连接共享,刚才说到
HTTP1.1
的head of line blocking
,那么在多路复用的情况下,blocking
已经不存在了。每个连接中可以包含多个流,而每个流中交错包含着来自两端的帧。也就是说同一个连接中是来自不同流的数据包混合在一起,如下图所示,每一块代表帧,而相同颜色块来自同一个流,每个流都有自己的ID
,在接收端会根据ID
进行重装组合,就是通过这样一种方式来实现多路复用。 - 头部压缩:
HTTP 2.0
通过HPACK
格式来压缩头部,使用了哈夫曼编码压缩、索引表来对头部大小做优化。索引表是把字符串和数字之间做一个匹配,比如method:GET
对应索引表中的2
,那么如果之前发送过这个值是,就会缓存起来,之后使用时发现之前发送过该Header
字段,并且值相同,就会沿用之前的索引来指代那个Header
值。 - Server Push:就是服务端可以主动推送一些东西给客户端,也被称为缓存推送。推送的资源可以备客户端日后之需,需要的时候直接拿出来用,提升了速率。
- 请求优先级设置,
HTTP/2
里的每个stream
都可以设置依赖 (Dependency
) 和权重,可以按依赖树分配优先级,解决了关键请求被阻塞的问题 - 流量控制,每个
http2
流都拥有自己的公示的流量窗口,它可以限制另一端发送数据。对于每个流来说,两端都必须告诉对方自己还有足够的空间来处理新的数据,而在该窗口被扩大前,另一端只被允许发送这么多数据。
HTTP 3.0 (QUIC Quick UDP Internet Connection)
- 线头阻塞(
HOL
)问题的解决更为彻底:基于TCP
的HTTP/2
,尽管从逻辑上来说,不同的流之间相互独立,不会相互影响,但在实际传输方面,数据还是要一帧一帧的发送和接收,一旦某一个流的数据有丢包,则同样会阻塞在它之后传输的流数据传输。而基于UDP
的QUIC
协议则可以更为彻底地解决这样的问题,让不同的流之间真正的实现相互独立传输,互不干扰。 - 切换网络时的连接保持:当前移动端的应用环境,用户的网络可能会经常切换,比如从办公室或家里出门,
WiFi
断开,网络切换为3G
或4G
。基于TCP
的协议,由于切换网络之后,IP
会改变,因而之前的连接不可能继续保持。而基于UDP
的QUIC
协议,则可以内建与TCP
中不同的连接标识方法,从而在网络完成切换之后,恢复之前与服务器的连接。
QUIC
很好地解决了当今传输层和应用层面临的各种需求,包括处理更多的连接,安全性,和低延迟。QUIC
融合了包括TCP
,TLS
,HTTP/2
等协议的特性,但基于UDP
传输。QUIC
的一个主要目标就是减少连接延迟,当客户端第一次连接服务器时,QUIC
只需要1RTT(Round-Trip Time)
的延迟就可以建立可靠安全的连接,相对于TCP+TLS
的1-3
次RTT
要更加快捷。之后客户端可以在本地缓存加密的认证信息,在再次与服务器建立连接时可以实现0-RTT
的连接建立延迟。QUIC
同时复用了HTTP/2
协议的多路复用功能(Multiplexing
),但由于QUIC
基于UDP
所以避免了HTTP/2
的线头阻塞(Head-of-Line Blocking
)问题。因为QUIC
基于UDP
,运行在用户域而不是系统内核,使得QUIC
协议可以快速的更新和部署,从而很好地解决了TCP
协议部署及更新的困难。
3.7 http-cache
max-age
:用来设置资源(representations
)可以被缓存多长时间,单位为秒;s-maxage
:和max-age
是一样的,不过它只针对代理服务器缓存而言;public
:指示响应可被任何缓存区缓存;private
:只能针对个人用户,而不能被代理服务器缓存;no-cache
:强制客户端直接向服务器发送请求,也就是说每次请求都必须向服务器发送。服务器接收到请求,然后判断资源是否变更,是则返回新内容,否则返回304,未变更。这个很容易让人产生误解,使人误以为是响应不被缓存。实际上Cache-Control:no-cache
是会被缓存的,只不过每次在向客户端(浏览器)提供响应数据时,缓存都要向服务器评估缓存响应的有效性。no-store
:禁止一切缓存(这个才是响应不被缓存的意思)。
3.8 什么是XSS攻击、CSRF攻击?有什么常见的预防。
XSS 攻击(Cross-Site Scripting):
XSS
攻击是一种常见的Web
安全漏洞。攻击者通过注入恶意脚本(通常为JavaScript
代码)到目标网站上的页面中,使用户在浏览该页面时执行这些恶意脚本。执行脚本可能导致用户数据泄露、账户被盗、基于浏览器的攻击等。
XSS 攻击预防:
- 输出转义/编码:对在网页显示的用户输入内容进行转义/编码,以防止
HTML/JavaScript
代码被执行。 - 输入验证:确保用户输入仅包含预期的字符集,限制输入长度, 验证格式以防止恶意脚本注入。
- 采用
CSP
(内容安全策略):通过为浏览器设定特定的安全策略来限制代码执行。例如,只允许执行来自可信域名的脚本。 - 使用
HttpOnly Cookie
:避免Cookie
串中敏感信息被暴露给脚本访问。 - 移除不需要的
XSS
攻击点:减少不必要的HTML
类型,过滤可执行的脚本标签等。
CSRF 攻击(Cross-Site Request Forgery):
CSRF
攻击是一种利用用户已登录状态发起非法请求的攻击手法。攻击者通过诱导用户浏览恶意页面或点击链接,利用用户的登录状态和权限在背后执行未经授权的操作。
CSRF 攻击预防:
- 使用
CSRF Token
:为每个请求生成一个随机的、唯一的CSRF
令牌,确保仅允许来自授权请求的操作。 - 验证
HTTP Referer
:检查请求的来源,确保请求仅来自合法的站点。 - 使用
SameSite Cookie
属性:限制第三方站点发送带有登录信息的请求,降低CSRF
攻击的风险。 - 添加验证码:对敏感操作添加验证码,确保只有经过人工确认的操作才能执行。
- 使用强制登录:较短的会话有效期,定期强制用户重新登录,限制攻击者的有效期。
- 遵循最低权限原则:对用户操作实施权限控制,确保用户只能访问其应有权限的资源和操作。
3.9 网络传输协议对比 Thrift vs Protobuf
Protobuf 数据压缩方式
varints
编码 (第一位表示0
表示没有,1
表示后面还有数据),后7
位正常表示Zigzag
编码 (符号位放到最后一位,-1
编码成1
,1
编码从2
,-2
编码成3
)sint32
和sint64
使用的zigzag
编码。PB
的tag
字段是用的varints
编码,第一个bit
表示是否有更多,后4
位表示tag index
(字段的序号为),后3
位表示wire_type
- 0:
varints
- 1:固定
64
位、 - 2:表示
tag - lenght - value
编码 - 5:表示固定
32
位
- 0:
string,bytes,message
都是采用tlv
编码
Thrift 数据压缩方式
3.10 Nginx解决惊群现象?
简而言之,惊群现象(thundering herd
)就是当多个进程和线程在同时阻塞等待同一个事件时,如果这个事件发生,会唤醒所有的进程,但最终只可能有一个进程/线程对该事件进行处理,其他进程/线程会在失败后重新休眠,这种性能浪费就是惊群。
- 早期
Nginx
解决惊群的方式是加锁,多个进程之间共享一个文件锁,只有在抢到这个锁的时候,这个进程才会将要监听的端口放到epoll
中,当epoll_wait
返回之后,nginx
会调用accept
把连接取出来,然后释放文件锁,让别的进程去监听。 SO_REUSEPORT
可以防止惊群效应,nginx
在1.11
版本以上,已经默认打开了SO_REUSEPORT
选项,解决了这个问题。Linux
从内核版本4.5
开始通过引入EPOLLEXCLUSIVE
标志来解决epoll
惊群现象。在使用这个标志时,只有一个线程会被唤醒,而不是唤醒所有等待该事件的线程。这可以显著降低在多线程编程中出现的惊群现象。Linux 2.6
版本之后,通过引入一个标记位WQ_FLAG_EXCLUSIVE
,解决掉了Accept
惊群效应。
3.11 Traceroute原理?
Traceroute
(又称路由追踪)是一种网络诊断工具,用于确定数据包在源主机和目的主机之间传输的路径。同时,它也提供了关于网络延迟和每个路径上的网络节点的详细信息。Traceroute
主要通过利用互联网协议(IP
)和用户数据报协议(UDP
)或Internet
控制报文协议(ICMP
)的特性来实现这个目标。
Traceroute
的原理如下:
- 发送数据包:
Traceroute
从源主机(发送方)向目标主机(接收方)发送一系列数据包。这些数据包的Time-To-Live(TTL)
值从1逐渐增加。TTL
是IP
数据包中的一个字段,用于指示数据包在网络上路由的最大跳数。当TTL
值为0
时,就不再继续进行路由。 - 路由节点递减
TTL
:在路径上的每个路由节点(路由器)在转发数据包时,会将TTL
值减1
。当TTL
变为0
时,路由节点会放弃转发该数据包,并通常会向源主机发送ICMP
“超时”消息(Time Exceeded)。 - 获取路径信息:源主机接收到
ICMP
“超时”消息后,会根据消息中的信息记录发送该消息的路由节点。通过逐步增加TTL
值,traceroute
可以获取源主机到目标主机之间的每个路径节点。 - 检测到目标主机:当数据包到达目标主机时,目标主机通常会发送一个
ICMP
“端口不可达”消息(Port Unreachable
),或者某些系统下的TTL 超时
消息,以通知源主机。收到这些消息的源主机即可确认路径已经完成,并结束traceroute
过程。 - 计算延迟:
Traceroute
通常为每个递增的TTL
值发送多个数据包以获得准确的平均延迟。它会计算发送数据包和接收ICMP
消息之间的时间差,以确定每个路由节点的延迟。 - 输出结果:最后,
traceroute
工具以易于阅读的格式显示源主机到目标主机间经过的所有路径节点和延迟信息。
3.12 路由协议? RIP、OSPF、BGP?
RIP
很早就被用在Internet
上,是最简单的路由协议。它是“路由信息协议(Route Information Protocol
)”的简写,主要传递路由信息,通过每隔30
秒广播一次路由表,维护相邻路由器的位置关系,同时根据收到的路由表信息计算自己的路由表信息。RIP
是一个距离矢量路由协议,最大跳数为15
跳,超过15
跳的网络则认为目标网络不可达。此协议通常用在网络架构较为简单的小型网络环境。分为RIPv1
和RIPv2
两个版本,后者支持VLSM
技术以及一系列技术上的改进。RIP
的收敛速度较慢。OSPF
协议是“开放式最短路径优先(Open Shortest Path First
)”的缩写,属于链路状态路由协议。OSPF
提出了“区域(area
)”的概念,每个区域中所有路由器维护着一个相同的链路状态数据库(LSDB
)。区域又分为骨干区域(骨干区域的编号必须为0
)和非骨干区域(非0编号区域),如果一个运行OSPF
的网络只存在单一区域,则该区域可以是骨干区域或者非骨干区域。如果该网络存在多个区域,那么必须存在骨干区域,并且所有非骨干区域必须和骨干区域直接相连。OSPF
利用所维护的链路状态数据库,通过最短路径优先算法(SPF
算法)计算得到路由表。OSPF
的收敛速度较快。由于其特有的开放性以及良好的扩展性,OSPF
协议在各种网络中广泛部署。BGP
为了维护各个ISP
的独立利益,标准化组织制定了ISP
间的路由协议BGP
。BGP
是“边界网关协议(Border Gateway Protocol
)”的缩写,处理各ISP
之间的路由传递。但是BGP
运行在相对核心的地位,需要用户对网络的结构有相当的了解,否则可能会造成较大损失。
3.13 NAT?P2P穿透?
NAT分类
NAT
从表面上看有三种类型:静态NAT
、动态地址NAT
、地址端口转换NAPT
。
(1)静态NAT
:静态地址转换将内部私网地址与合法公网地址进行一对一的转换,且每个内部地址的转换都是确定的。
(2)动态NAT
:动态地址转换也是将内部本地地址与内部合法地址一对一的转换,但是动态地址转换是从合法地址池中动态选择一个未使用的地址来对内部私有地址进行转换。
(3)NAPT
:它也是一种动态转换,而且多个内部地址被转换成同一个合法公网地址,使用不同的端口号来区分不同的主机,不同的进程。
从实现的技术角度,又可以将NAT
分成如下几类:全锥NAT(Full Cone NAT)
、限制性锥NAT(Restricted Cone NAT)
、端口限制性锥NAT( Port Restricted Cone NAT)
、对称NAT ( Symmetric NAT)
。
(1)全锥NAT
:全锥NAT
把所有来自相同内部IP
地址和端口的请求映射到相同的外部IP
地址和端口。任何一个外部主机均可通过该映射发送数据包到该内部主机。 (电信)
(2)限制性锥NAT
:限制性锥NAT
把所有来自相同内部IP
地址和端口的请求映射到相同的外部IP
地址和端口。但是,和全锥NAT
不同的是:只有当内部主机先给外部主机发送数据包,该外部主机才能向该内部主机发送数据包。
(3)端口限制性锥NAT
:端口限制性锥NAT
与限制性锥NAT
类似,只是多了端口号的限制,即只有内部主机先向外部地址:端口号对发送数据包,该外部主机才能使用特定的端口号向内部主机发送数据包。(联通)
(4)对称NAT
:对称NAT
与上述3种类型都不同,不管是全锥NAT
,限制性锥NAT
还是端口限制性锥NAT
,它们都属于锥NAT(Cone NAT)
。当同一内部主机使用相同的端口与不同地址的外部主机进行通信时, 对称NAT
会重新建立一个Session
,为这个Session
分配不同的端口号,或许还会改变IP
地址。
3.14 操作系统收取数据包原理
3.15 OSI 七层和 TCP/IP 四层
3.16 网络包接收流程
网络帧到达网卡-> DMA
把数据放到收到队列 -> 硬中断-> 网卡中断处理程序会为 网络帧分配(SK_Buff
)-> 拷贝到 SK_Buff
缓冲区 -> 软中断 -> 通知内核收到行的网络帧
接下来内核会从协议栈缓存区 取出 网络帧,从下到上逐层解析比如 -> 链路层检查报文合法性,找出上层协议。
->网络层取出IP
头,判断网络包下一步走向,比如是交给上层处理还是转发,当确认是发送到本机以后,就会取出上层协议(TCP
还是UDP
),去掉IP头给上层处理
-> 根据 IP+Port
四元组 做表示 找到对应Socket
,把数据拷贝到Scoket
接收缓存中。
3.17 其他
路径MTU
ARP
ICMP
ICMP地址掩码请求和应答报文
“UDP端口不可达”例子中返回的ICMP报文
Ping
RIP