计算机网络基础

1. TCP/IP网络模型

1.1 应用层

为用户提供应用功能,比如 HTTP、DNS等。

1.2 传输层

为应用层提供网络支持,TCP 和 UDP。

TCP

TCP:流量控制、超时重传、拥塞控制等,这些都是为了保证数据包能可靠地传输给对方。

分段:应用需要传输的数据可能会非常大,如果直接传输就不好控制,因此当传输层的数据包大小超过 MSS(TCP 最大报文段长度) ,就要将数据包分块,这样即使中途有一个分块丢失或损坏了,只需要重新发送这一个分块,而不用重新发送整个数据包。在 TCP 协议中,我们把每个分块称为一个 TCP 段

传输层的报文中会携带端口号,因此接收方可以识别出该报文是发送给哪个进程。

UDP

UDP:简单到只负责发送数据包,不保证数据包是否能抵达对方,但它实时性相对更好,传输效率也高。

1.3 网络层

网络层主要负责将数据从源节点传输到目标节点(IP地址)。

IP 协议会将传输层的报文作为数据部分,再加上 IP 包头组装成 IP 报文,如果 IP 报文大小超过 MTU(以太网中一般为 1500 字节)就会再次进行分片,得到一个即将发送到网络的 IP 报文。

IPV4(32位),前面是网络号,后面是主机号,通过子网掩码区分。

网络层核心功能

  • 转发:根据数据包的目标IP地址查找其转发表(Forwarding Table),确定将数据包发送到哪个接口。
  • 路由:路由是指确定数据包从源地址到目的地址的最佳路径的过程。用路由协议(如RIP、OSPF、BGP等)与其他路由器交换信息,以构建和维护路由表(Routing Table)。

1.4 网络接口层(传输层/物理层)

网络接口层主要为网络层提供「链路级别」传输的服务,负责在底层网络上发送原始数据包,工作在网卡这个层次,使用 MAC 地址来标识网络上的设备。

把IP报文加上MAC地址,封装成数据帧(Data frame)发送到网络上。

MAC 头部是以太网使用的头部,它包含了接收方和发送方的 MAC 地址等信息,我们可以通过 ARP 协议获取对方的 MAC 地址。

ARP协议

在发送数据包时,如果目标主机不是本地局域网,填入的MAC地址是路由器,也就是把数据包转发给路由器,路由器一直转发下一个路由器,直到转发到目标主机的路由器,发现 IP 地址是自己局域网内的主机,就会 arp 请求获取目标主机的 MAC 地址,从而转发到这个服务器主机。网络传输中,源IP地址和目标IP地址是不会变的,源 MAC 地址和目标 MAC 地址是会变化的。

1.5 总结

image-20250118120716732

2. URL

URL(Uniform Resource Locators),即统一资源定位器。

image-20250118122911116

3. DNS

DNS主要使用了UDP,有些情况也使用TCP。

如果Type=A,则Name是主机名信息,Value 是该主机名对应的 IP 地址。这样的 RR 记录了一条主机名到 IP 地址的映射。

如果Type=CNAME (Canonical Name Record,真实名称记录) ,则Value是别名为Name的主机对应的规范主机名。Value值才是规范主机名。CNAME 记录将一个主机名映射到另一个主机名。CNAME 记录用于为现有的 A 记录创建别名。下文有示例。

NAME                    TYPE   VALUE
--------------------------------------------------
bar.example.com.        CNAME  foo.example.com.
foo.example.com.        A      192.0.2.23

image-20250118195340937

image-20250118195242137

浏览器会先看自身有没有对这个域名的缓存,如果有,就直接返回,如果没有,就去问操作系统,操作系统也会去看自己的缓存,如果有,就直接返回,如果没有,再去 hosts 文件看,也没有,才会去问「本地 DNS 服务器」。

4. 键入网址到网页显示

1.在浏览器中输入指定网页的 URL。

2.浏览器通过 DNS 协议,获取域名对应的 IP 地址。

3.浏览器根据 IP 地址和端口号,向目标服务器发起一个 TCP 连接请求。

4.浏览器在 TCP 连接上,向服务器发送一个 HTTP 请求报文,请求获取网页的内容。

5.服务器收到 HTTP 请求报文后,处理请求,并返回 HTTP 响应报文给浏览器。

6.浏览器收到 HTTP 响应报文后,解析响应体中的 HTML 代码,渲染网页的结构和样式,同时根据 HTML 中的其他资源的 URL(如图片、CSS、JS 等),再次发起 HTTP 请求,获取这些资源的内容,直到网页完全加载显示。

7.浏览器在不需要和服务器通信时,可以主动关闭 TCP 连接,或者等待服务器的关闭请求。

5.OSI七层

OSI 模型将表示层和会话层独立出来,而 TCP/IP 模型将它们合并到应用层。

  • OSI 模型是理论模型,分层更细致,适合教学和标准化。
  • TCP/IP 模型是实际模型,分层更简洁,广泛用于互联网通信。

image-20250226193125178

HTTP

1. 基本概念

HTTP 是超文本传输协议。

详细解释的话:协议、传输、超文本。

HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」。

常见状态码:

2xx 类状态码表示服务器成功处理了客户端的请求,也是我们最愿意看到的状态。

3xx 类状态码表示客户端请求的资源发生了变动,需要客户端用新的 URL 重新发送请求获取资源,也就是重定向

4xx 类状态码表示客户端发送的报文有误

  • 403 Forbidden表示服务器禁止访问资源,并不是客户端的请求出错。
  • 404 Not Found表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端。

常见字段:

  • Host 字段:域名
  • Content-Length 字段:本次回应的数据长度。
  • Connection: Keep-Alive:可以使用同一个 TCP 连接来发送和接收多个 HTTP 请求/应答,避免了连接建立和释放的开销,这个方法称为 HTTP 长连接
  • Content-Type 字段:本次数据是什么格式。
  • Content-Encoding 字段:使用了什么压缩格式

技术:

长连接:使用同一个 TCP 连接来发送和接收多个 HTTP 请求/应答,避免了连接建立和释放的开销,这个方法称为 HTTP 长连接

流水线:客户端可以先一次性发送多个请求,而在发送过程中不需先等待服务器的回应

image-20250119175734018

2. Get和Post区别

GET 方法就是安全且幂等的,因为它是「只读」操作,无论操作多少次,服务器上的数据都是安全的,且每次的结果都是相同的。所以,可以对 GET 请求的数据做缓存,这个缓存可以做到浏览器本身上(彻底避免浏览器发请求),也可以做到代理上(如nginx),而且在浏览器中 GET 请求可以保存为书签

​ POST因为是「新增或提交数据」的操作,会修改服务器上的资源,所以是不安全的,且多次提交数据就会创建多个资源,所以不是幂等的。所以,浏览器一般不会缓存 POST 请求,也不能把 POST 请求保存为书签

3. HTTP 与 HTTPS

3.1 二者区别

  • HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输
  • HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。
  • 两者的默认端口不一样,HTTP 默认端口号是 80,HTTPS 默认端口号是 443。
  • HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。

3.2 HTTPS 解决了 HTTP 的哪些问题?

  • 窃听风险,比如通信链路上可以获取通信内容,用户号容易没。
  • 篡改风险,比如强制植入垃圾广告,视觉污染,用户眼容易瞎。
  • 冒充风险,比如冒充淘宝网站,用户钱容易没。
  • 信息加密:交互信息无法被窃取,但你的号会因为「自身忘记」账号而没。
  • 校验机制:无法篡改通信内容,篡改了就不能正常显示,但百度「竞价排名」依然可以搜索垃圾广告。
  • 身份证书:证明淘宝是真的淘宝网,但你的钱还是会因为「剁手」而没。

3.3 如何解决?

  • 摘要算法的方式来实现完整性,它能够为数据生成独一无二的「指纹」,指纹用于校验数据的完整性,解决了篡改的风险。
  • 将服务器公钥放入到数字证书中,解决了冒充的风险。

1.混合加密:实现信息的机密性,解决了窃听的风险

HTTPS 采用的是对称加密非对称加密结合的「混合加密」方式:

  • 在通信建立前采用非对称加密的方式得到「会话秘钥」,后续就不再使用非对称加密。
  • 在通信过程中全部使用对称加密的「会话秘钥」的方式加密明文数据。

采用「混合加密」的方式的原因:

  • 对称加密只使用一个密钥,运算速度快,密钥必须保密,无法做到安全的密钥交换。
  • 非对称加密使用两个密钥:公钥和私钥,公钥可以任意分发而私钥保密,解决了密钥交换问题但速度慢。

2.摘要算法+数字签名:无法篡改通信内容

用摘要算法(哈希函数)来计算出内容的哈希值,也就是内容的「指纹」,这个哈希值是唯一的,且无法通过哈希值推导出内容

image-20250118192228654

3.身份证书:解决了冒充的风险

image-20250118194934717

总结:

image-20250118190158059

TCP

TCP和UDP都使用IP协议。

1. TCP基本概念

TCP 是面向连接的、可靠的、基于字节流的传输层通信协议。

TCP工作在传输层,确保网络包是无损坏、无间隔、非冗余和按序的

TCP有一个首部长度,TCP的数据长度=IP总长度-IP首部长度-TCP首部长度,其中 IP 总长度 和 IP 首部长度,在 IP 首部格式是已知的。TCP 首部长度,则是在 TCP 首部格式已知的,所以就可以求得 TCP 数据的长度。

序列号:在建立连接时由计算机生成的随机数作为其初始值,通过 SYN 包传给接收端主机,每发送一次数据,就「累加」一次该「数据字节数」的大小。用来解决网络包乱序问题。

确认应答号:指下一次「期望」收到的数据的序列号,发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。用来解决丢包的问题。

  • 公式一:序列号 = 上一次发送的序列号 + len(数据长度)。特殊情况,如果上一次发送的报文是 SYN 报文或者 FIN 报文,则改为 上一次发送的序列号 + 1。
  • 公式二:确认号 = 上一次收到的报文中的序列号 + len(数据长度)。特殊情况,如果收到的是 SYN 报文或者 FIN 报文,则改为上一次收到的报文中的序列号 + 1。

标志位:ACK.SYN.FIN.RST(RST标志位用于强制关闭一个TCP连接。它的主要作用是通知对方当前的连接不再有效)

image-20250119124152176

TCP四元组:

image-20250119122425285

2. UDP基本概念

UDP 不提供复杂的控制机制,利用 IP 提供面向「无连接」的通信服务。

UDP 协议真的非常简,头部固定只有 8 个字节(64 位),UDP 的头部格式如下:

UDP数据长度=包长度-8。

image-20250119123923536

3. TCP和UDP

3.1 二者区别

1. 连接

  • TCP 是面向连接的传输层协议,传输数据前先要建立连接。
  • UDP 是不需要连接,即刻传输数据。

2. 服务对象

  • TCP 是一对一的两点服务,即一条连接只有两个端点。
  • UDP 支持一对一、一对多、多对多的交互通信

3. 可靠性

  • TCP 是可靠交付数据的,数据可以无差错、不丢失、不重复、按序到达。
  • UDP 是尽最大努力交付,不保证可靠交付数据。

4. 拥塞控制、流量控制

  • TCP 有拥塞控制和流量控制机制,保证数据传输的安全性。
  • UDP 则没有,即使网络非常拥堵了,也不会影响 UDP 的发送速率。

5. 首部开销

  • TCP 首部长度较长,会有一定的开销,首部在没有使用「选项」字段时是 20 个字节,如果使用了「选项」字段则会变长的。
  • UDP 首部只有 8 个字节,并且是固定不变的,开销较小。

6. 传输方式

  • TCP 是流式传输,没有边界,但保证顺序和可靠。
  • UDP 是一个包一个包的发送,是有边界的,但可能会丢包和乱序。

7. 分片不同

  • TCP 的数据大小如果大于 MSS 大小,则会在传输层进行分片,目标主机收到后,也同样在传输层组装 TCP 数据包,如果中途丢失了一个分片,只需要传输丢失的这个分片。
  • UDP 的数据大小如果大于 MTU 大小,则会在 IP 层进行分片,目标主机收到后,在 IP 层组装完数据,接着再传给传输层。

3.2 TCP和UDP的应用场景

由于 TCP 是面向连接,能保证数据的可靠性交付,因此经常用于:FTP 文件传输;HTTP / HTTPS;

由于 UDP 面向无连接,它可以随时发送数据,再加上 UDP 本身的处理既简单又高效,因此经常用于:视频、音频等多媒体通信;包总量较少的通信,如 DNSSNMP 等。

3.3 可以使用同一个端口吗

可以,传输层有两个传输协议分别是 TCP 和 UDP,在内核中是两个完全独立的软件模块。

当主机收到数据包后,可以在 IP 包头的「协议号」字段知道该数据包是 TCP/UDP,所以可以根据这个信息确定送给哪个模块(TCP/UDP)处理,送给 TCP/UDP 模块的报文根据「端口号」确定送给哪个应用程序处理。

因此,TCP/UDP 各自的端口号也相互独立,如 TCP 有一个 80 号端口,UDP 也可以有一个 80 号端口,二者并不冲突。

4. TCP连接建立

4.1 易错点

ACK 报文是不会有重传的,当 ACK 丢失了,就由对方重传对应的报文

4.2 建立流程

SYN和ACK是标志位,Seq Num是序列号,ACK num是确认应答号。

第三次握手是可以携带数据的,前两次握手是不可以携带数据的

image-20250119130430785

4.3 为什么是三次握手?不是两次、四次?

三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。

  1. 第一次握手:Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常
  2. 第二次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:对方发送正常,自己接收正常
  3. 第三次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送、接收正常

三次握手就能确认双方收发功能都正常,缺一不可。

除此之外一个别的观点:详细看小林coding:https://xiaolincoding.com/network/3_tcp/tcp_interview.html#%E4%B8%BA%E4%BB%80%E4%B9%88%E6%98%AF%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B-%E4%B8%8D%E6%98%AF%E4%B8%A4%E6%AC%A1%E3%80%81%E5%9B%9B%E6%AC%A1

  • 「两次握手」:无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号;
  • 「四次握手」:三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数。

4.4 为什么每次建立 TCP 连接时,初始化的序列号都要求不一样呢?

很大程度上能够避免历史报文被下一个相同四元组的连接接收

4.5 既然 IP 层会分片,为什么 TCP 层还需要 MSS 呢?

因为 IP 层本身没有超时重传机制,它由传输层的 TCP 来负责超时和重传。

当某一个 IP 分片丢失后,接收方的 IP 层就无法组装成一个完整的 TCP 报文(头部 + 数据),也就无法将数据报文送到 TCP 层,所以接收方不会响应 ACK 给发送方,因为发送方迟迟收不到 ACK 确认报文,所以会触发超时重传,就会重发「整个 TCP 报文(头部 + 数据)」。

因此,可以得知由 IP 层进行分片传输,是非常没有效率的。

经过 TCP 层分片后,如果一个 TCP 分片丢失后,进行重发时也是以 MSS 为单位,而不用重传所有的分片,大大增加了重传的效率。

4.6 三次握手丢失会发生什么

超时重传(尝试几次,不行就断开连接),看小林coding

4.7 什么是 SYN 攻击?如何避免 SYN 攻击?

SYN 攻击方式最直接的表现就会把 TCP 半连接队列打满,这样当 TCP 半连接队列满了,后续再在收到 SYN 报文就会丢弃,导致客户端无法和服务端建立连接。

增大半连接队列,减少 SYN+ACK 重传次数。

5. TCP连接断开

5.1 建立流程

  • 客户端打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文,之后客户端进入 FIN_WAIT_1 状态。
  • 服务端收到该报文后,就向客户端发送 ACK 应答报文,接着服务端进入 CLOSE_WAIT 状态。
  • 客户端收到服务端的 ACK 应答报文后,之后进入 FIN_WAIT_2 状态。
  • 等待服务端处理完数据后,也向客户端发送 FIN 报文,之后服务端进入 LAST_ACK 状态。
  • 客户端收到服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 TIME_WAIT 状态
  • 服务端收到了 ACK 应答报文后,就进入了 CLOSE 状态,至此服务端已经完成连接的关闭。
  • 客户端在经过 2MSL 一段时间后,自动进入 CLOSE 状态,至此客户端也完成连接的关闭。

你可以看到,每个方向都需要一个 FIN 和一个 ACK,因此通常被称为四次挥手

这里一点需要注意是:主动关闭连接的,才有 TIME_WAIT 状态。

image-20250119141935633

5.2 为什么是四次挥手?

  • 关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。
  • 服务端收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。

  • 第一次挥手:A 说“我没啥要说的了”

  • 第二次挥手:B 回答“我知道了”,但是 B 可能还会有要说的话,A 不能要求 B 跟着自己的节奏结束通话
  • 第三次挥手:于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”
  • 第四次挥手:A 回答“知道了”,这样通话才算结束。

为什么不能把服务端发送的 ACK 和 FIN 合并起来,变成三次挥手?

因为服务端收到客户端断开连接的请求时,可能还有一些数据没有发完,这时先回复 ACK,表示接收到了断开连接的请求。等到数据发完之后再发 FIN,断开服务端到客户端的数据传送。

5.3 四次挥手丢失会发生什么?

看小林coding

5.4 为什么第四次挥手客户端需要等待 2*MSL时间后才进入 CLOSED 状态?

第四次挥手时,客户端发送给服务端的 ACK 有可能丢失,如果服务端因为某些原因而没有收到 ACK 的话,服务端就会重发 FIN,如果客户端在 2*MSL 的时间内收到了 FIN,就会重新发送 ACK 并再次等待 2MSL,防止 Server 没有收到 ACK 而不断重发 FIN。

5.5 为什么 TIME_WAIT 等待的时间是 2MSL?

可以看到 2MSL时长 这其实是相当于至少允许报文丢失一次。比如,若 ACK 在一个 MSL 内丢失,这样被动方重发的 FIN 会在第 2 个 MSL 内到达,TIME_WAIT 状态的连接可以应对。

image-20250119143630361

5.6 如果已经建立了连接,但是客户端突然出现故障了怎么办?

通过心跳机制(保活机制)、超时设置等方法来管理的。服务器可能会定期发送数据包(如心跳包)来检查客户端是否仍然可用。

如果服务器在一定时间内没有收到来自客户端的数据包,它可能会认为客户端出现故障。服务器会根据其配置的超时设置来主动关闭连接。

如果没有开启keep-alive(不是http中的),呢么TCP连接永远不会断。

image-20250119175536879

6. TCP是如何保障可靠的

6.1 概述

TCP 是通过序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输的。

6.2 重传机制

6.2.1 超时重传

重传机制的其中一个方式,就是在发送数据时,设定一个定时器,当超过指定的时间后,没有收到对方的 ACK 确认应答报文,就会重发该数据,也就是我们常说的超时重传

image-20250119151358720

超时重传时间 RTO 的值应该略大于报文往返 RTT 的值。

实际上RTO是随着网络情况动态变化的。

每当遇到一次超时重传的时候,都会将下一次超时时间间隔设为先前值的两倍。两次超时,就说明网络环境差,不宜频繁反复发送。

image-20250119151525935

6.2.2 快速重传

当收到三个相同的 ACK 报文时,会在定时器过期之前,重传丢失的报文段。

注意:下图使用了发送窗口,发送方一下子发送了连续五个(而不是发一个等一个ack)

image-20250119151727398

面临的问题,重传什么?

  • 如果只选择重传 Seq2 一个报文,那么重传的效率很低。因为对于丢失的 Seq3 报文,还得在后续收到三个重复的 ACK3 才能触发重传。
  • 如果选择重传 Seq2 之后已发送的所有报文,虽然能同时重传已丢失的 Seq2 和 Seq3 报文,但是 Seq4、Seq5、Seq6 的报文是已经被接收过了,对于重传 Seq4 ~Seq6 折部分数据相当于做了一次无用功,浪费资源。

6.2.3 SACK 方法

选择性确认:这种方式需要在 TCP 头部「选项」字段里加一个 SACK 的东西,它可以将已收到的数据的信息发送给「发送方」,这样发送方就可以知道哪些数据收到了,哪些数据没收到,知道了这些信息,就可以只重传丢失的数据

image-20250119152519908

6.2.4 Duplicate SACK

6.3 滑动窗口

不使用滑动窗口,效率低,发一下等一下ack,

image-20250119154324670

6.3.1 累计确认

image-20250119154407052

通常窗口的大小是由接收方的窗口大小来决定的,接收窗口的大小是约等于发送窗口的大小的,但不完全相等。

发送窗口的值是swnd = min(cwnd, rwnd),也就是拥塞窗口和接收窗口中的最小值。

实际上发送和接收窗口都是放在操作系统内存缓冲区中的,而操作系统的缓冲区,会被操作系统调整

6.3.2 发送方窗口

image-20250119154509794

image-20250119154530015

6.3.3 接收方窗口

image-20250119154647737

6.4 流量控制

发送方不能无脑的发数据给接收方,要考虑接收方处理能力。

TCP 提供一种机制可以让「发送方」根据「接收方」的实际接收能力控制发送的数据量,这就是所谓的流量控制。

接收方 向 发送方 通告窗口大小时,是通过 ACK 报文来通告的。

image-20250119160424623

窗口探测的次数一般为 3 次,每次大约 30-60 秒(不同的实现可能会不一样)。如果 3 次过后接收窗口还是 0 的话,有的 TCP 实现就会发 RST 报文来中断连接。

6.5 拥塞控制

前面的流量控制是避免「发送方」的数据填满「接收方」的缓存,但是并不知道网络的中发生了什么。

一般来说,计算机网络都处在一个共享的环境。因此也有可能会因为其他主机之间的通信使得网络拥堵。TCP是无私的协议。

目的是:避免「发送方」的数据填满整个网络

那么怎么知道当前网络是否出现了拥塞呢?

其实只要「发送方」没有在规定时间内接收到 ACK 应答报文,也就是发生了超时重传,就会认为网络出现了拥塞。

6.5.1 慢启动

当发送方每收到一个 ACK,拥塞窗口 cwnd 的大小就会加 1。

  • 连接建立完成后,一开始初始化 cwnd = 1表示可以传一个 MSS 大小的数据
  • 当收到一个 ACK 确认应答后,cwnd 增加 1,于是一次能够发送 2 个
  • 当收到 2 个的 ACK 确认应答后, cwnd 增加 2,于是就可以比之前多发2 个,所以这一次能够发送 4 个
  • 当这 4 个的 ACK 确认到来的时候,每个确认 cwnd 增加 1, 4 个确认 cwnd 增加 4,于是就可以比之前多发 4 个,所以这一次能够发送 8 个。

image-20250119163737157

有一个叫慢启动门限 ssthresh (slow start threshold)状态变量。

  • cwnd < ssthresh 时,使用慢启动算法。
  • cwnd >= ssthresh 时,就会使用「拥塞避免算法」

6.5.2 拥塞避免算法

拥塞窗口 cwnd 「超过」慢启动门限 ssthresh 就会进入拥塞避免算法。

那么进入拥塞避免算法后,它的规则是:每当收到一个 ACK 时,cwnd 增加 1/cwnd。

  • 当 8 个 ACK 应答确认到来时,每个确认增加 1/8,8 个 ACK 确认 cwnd 一共增加 1,于是这一次能够发送 9 个 MSS 大小的数据,变成了线性增长。

image-20250119164115467

6.5.3 超时重传

出现了超时重传,说明网络拥堵,减小拥塞窗口可以降低发送速率,减轻网络负担,帮助网络恢复到更稳定的状态。

  • ssthresh 设为 cwnd/2
  • cwnd 重置为 1 (是恢复为 cwnd 初始化值,我这里假定 cwnd 初始化值 1)

image-20250119164318959

6.5.4 快速恢复

快速重传: 当发送端连续收到3个重复的确认报文端段的时候,tcp就认为拥塞发生了。然后会立即重传丢失的报文段。

快速恢复机制一般和快速重传机制同时使用。快速恢复机制如下:

快速恢复算法是认为,你还能收到 3 个重复 ACK 说明网络也不那么糟糕,所以没有必要像 RTO 超时那么强烈。

  • ssthresh = cwnd/2
  • cwnd = ssthresh + 3, 加 3 代表快速重传时已经确认接收到了 3 个重复的数据包;
  • 如果再收到重复的 ACK,那么 cwnd 增加 1;说明网络的状况并没有恶化,允许发送方在拥塞恢复期间更有效地利用网络带宽,而不必完全回到慢开始状态,提高了效率。
  • 如果收到新数据的 ACK 后,把 cwnd 设置为第一步中的 ssthresh 的值,原因是该 ACK 确认了新的数据,说明从 duplicated ACK 时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进入拥塞避免状态;

注意:在旧的tcp拥塞控制算法中,快速重传之后会进入慢启动阶段,而新的tcp拥塞控制算法在快速重传之后进入快速恢复阶段。

image-20250119165345025

7.杂项

7.1如何理解是 TCP 面向字节流协议?

UDP 是面向报文的协议:

当用户消息通过 UDP 协议传输时,操作系统不会对消息进行拆分,在组装好 UDP 头部后就交给网络层来处理,所以发出去的 UDP 报文中的数据部分就是完整的用户消息,也就是每个 UDP 报文就是一个用户消息的边界,这样接收方在接收到 UDP 报文后,读一个 UDP 报文就能读取到完整的用户消息。

TCP 是面向字节流的协议:

发送方准备发送 「Hi.」和「I am Xiaolin」这两个消息。

image-20250119171006811

我们不知道 「Hi.」和 「I am Xiaolin」 这两个用户消息是如何进行 TCP 分组传输的。

因此,我们不能认为一个用户消息对应一个 TCP 报文,正因为这样,所以 TCP 是面向字节流的协议

当两个消息的某个部分内容被分到同一个 TCP 报文时,就是我们常说的 TCP 粘包问题,这时接收方不知道消息的边界的话,是无法读出有效的消息。

要解决这个问题,要交给应用程序

如何解决粘包?

特殊字符作为边界:我们可以在两个用户消息之间插入一个特殊的字符串,这样接收方在接收数据时,读到了这个特殊字符,就把认为已经读完一个完整的消息。HTTP 通过设置回车符、换行符作为 HTTP 报文协议的边界。

7.2 已建立连接的TCP,收到SYN会发生什么?

image-20250119171749950

7.3 四次挥手中收到乱序的 FIN 包会如何处理?

若服务端在二三次挥手间或四次挥手前发送的数据包因网络阻塞,导致第三次挥手的 FIN 包比数据包先到主动关闭方,主动关闭方收到 FIN 是否会进入 timewait 状态以及延迟数据包能否正常接收处理?

在 FIN_WAIT_2 状态下收到乱序的 FIN 报文,会被加入 “乱序队列” 。等收到之前被网络延迟的数据包时,若乱序队列中有与当前报文序列号连续的报文且该报文有 FIN 标志,这时才会进入 TIME_WAIT 状态。

https://xiaolincoding.com/network/3_tcp/out_of_order_fin.html#tcp-%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90

7.4 在 TIME_WAIT 状态的 TCP 连接,收到 SYN 后会发生什么?

  • 如果客户端的 SYN 的「序列号」比服务端「期望下一个收到的序列号」要并且SYN 的「时间戳」比服务端「最后收到的报文的时间戳」要。那么就会重用该四元组连接,跳过 2MSL 而转变为 SYN_RECV 状态,接着就能进行建立连接过程。
  • 如果客户端的 SYN 的「序列号」比服务端「期望下一个收到的序列号」要或者SYN 的「时间戳」比服务端「最后收到的报文的时间戳」要。那么就会再回复一个第四次挥手的 ACK 报文,客户端收到后,发现并不是自己期望收到确认号,就回 RST 报文给服务端

7.5 TCP 连接,一端断电和进程崩溃有什么区别?

7.6 拔掉网线后, 原本的 TCP 连接还存在吗?

等价于=客户端宕机

客户端拔掉网线后,并不会直接影响 TCP 连接状态。所以,拔掉网线后,TCP 连接是否还会存在,关键要看拔掉网线之后,有没有进行数据传输。

https://xiaolincoding.com/network/3_tcp/tcp_unplug_the_network_cable.html#%E6%80%BB%E7%BB%93

7.7 TCP Keepalive 和 HTTP Keep-Alive 是一个东西吗?

这两个完全是两样不同东西

HTTP 的 Keep-Alive 也叫 HTTP 长连接,该功能是由「应用程序」实现的,可以使得用同一个 TCP 连接来发送和接收多个 HTTP 请求/应答,减少了 HTTP 短连接带来的多次 TCP 连接建立和释放的开销。

TCP 的 Keepalive 也叫 TCP 保活机制,该功能是由「内核」实现的,当客户端和服务端长达一定时间没有进行数据交互时,内核为了确保该连接是否还有效,就会发送探测报文,来检测对方是否还在线,然后来决定是否要关闭该连接。

7.8 TCP 四次挥手,可以变成三次吗?

TCP 四次挥手中,能不能把第二次的 ACK 报文, 放到第三次 FIN 报文一起发送?

不太好,有点暴力,因为服务端收到客户端断开连接的请求时,可能还有一些数据没有发完,这时先回复 ACK,表示接收到了断开连接的请求。等到数据发完之后再发 FIN,断开服务端到客户端的数据传送。

IP

0. 基本知识

IP 包中有一个字段叫做 TTLTime To Live,生存周期),它的值随着每经过一次路由器就会减 1,直到减到 0 时该 IP 包会被丢弃。

此时,路由器将会发送一个 ICMP 超时消息给发送端主机,并通知该包已被丢弃。

image-20250120135207202

1. IP和MAC关系

源IP地址和目标IP地址在传输过程中是不会变化的(前提:没有使用 NAT 网络),只有源 MAC 地址和目标 MAC 一直在变化。

image-20250119181328882

2. IP 地址的分类

目前不用了。

image-20250119181530872

image-20250119181625803

  • 主机号全为 1 指定某个网络下的所有主机,用于广播
  • 主机号全为 0 指定某个网络

广播分为本地广播(只在局域网内,路由器不转发),和直接广播(有安全性问题)

image-20250120103759881

IP分类的优点:简单明了、选路(基于网络地址)简单

缺点:不能很好的与现实网络匹配。

  • C 类地址能包含的最大主机数量实在太少了,只有 254 个,估计一个网吧都不够用。
  • 而 B 类地址能包含的最大主机数量又太多了,6 万多台机器放在一个网络下面,一般的企业基本达不到这个规模,闲着的地址就是浪费。

3. 无分类地址 CIDR

3.1 基本内容

表示形式 a.b.c.d/x,其中 /x 表示前 x 位属于网络号, x 的范围是 0 ~ 32,这就使得 IP 地址更加具有灵活性。

比如 10.100.122.2/24,这种地址表示形式就是 CIDR,/24 表示前 24 位是网络号,剩余的 8 位是主机号。

注意主机号,全1是广播地址。全0也有用处。

image-20250120105002797

也可以使用子网掩码(掩盖掉主机号)。

image-20250120104940654

3.2 为什么要分离网络号和主机号?

因为两台计算机要通讯,首先要判断是否处于同一个广播域内,即网络地址是否相同。如果网络地址相同,表明接受方在本网络上,那么可以把数据包直接发送到目标主机。

路由器寻址工作中,也就是通过这样的方式来找到对应的网络号的,进而把数据包转发给对应的网络内。

3.3 怎么进行子网划分?

子网掩码还有一个作用,那就是划分子网

子网划分实际上是将主机地址分为两个部分:子网网络地址和子网主机地址。形式如下

image-20250120105804071

image-20250120110318400

这样我们就可以根据ip地址和子网掩码,区分出网络地址、子网地址、主机地址

image-20250120110353887

image-20250120110338710

4. 公有 IP 地址与私有 IP 地址

平时我们办公室、家里、学校用的 IP 地址,一般都是私有 IP 地址。

因为这些地址允许组织内部的 IT 人员自己管理、自己分配,而且可以重复。因此,你学校的某个私有 IP 地址和我学校的可以是一样的。

5. IP 地址与路由控制

image-20250120110939626

计算机使用一个特殊的 IP 地址 127.0.0.1 作为环回地址。与该地址具有相同意义的是一个叫做 localhost 的主机名。使用这个 IP 或主机名时,数据包不会流向网络。

6. IP 分片与重组

在分片传输中,一旦某个分片丢失,则会造成整个 IP 数据报作废,所以 TCP 引入了 MSS 也就是在 TCP 层进行分片不由 IP 层分片。

对于 UDP 我们尽量不要发送一个大于 MTU 的数据报文。

image-20250120111240947

7. IPv6 基本认识

IPv4 的地址是 32 位的,大约可以提供 42 亿个地址,但是早在 2011 年 IPv4 地址就已经被分配完了。

但是 IPv6 的地址是 128 位的,这可分配的地址数量是大的惊人,说个段子 IPv6 可以保证地球上的每粒沙子都能被分配到一个 IP 地址。

  • IPv6 可自动配置,即使没有 DHCP 服务器也可以实现自动分配IP地址,真是便捷到即插即用啊。
  • IPv6 包头包首部长度采用固定的值 40 字节,去掉了包头校验和,简化了首部结构,减轻了路由器负荷,大大提高了传输的性能
  • IPv6 有应对伪造 IP 地址的网络安全功能以及防止线路窃听的功能,大大提升了安全性

IPv4 地址长度共 32 位,是以每 8 位作为一组,并用点分十进制的表示方式。

IPv6 地址长度是 128 位,是以每 16 位作为一组,每组用冒号 「:」 隔开。

image-20250120111457180

image-20250120111714281

8. IP 协议相关技术

8.1 DNS

前面写了

8.2 ARP

操作系统通常会把第一次通过 ARP 获取的 MAC 地址缓存起来,以便下次直接从缓存中找到对应 IP 地址的 MAC 地址。

image-20250120111923719

同一个子网内:主机A首先比较目的IP地址与自己的IP地址是否在同一子网中,如果在同一子网,则向本网发送ARP广播,获得目标IP所对应的MAC地址;

不同子网:

  1. 检查路由表:主机A检查其路由表,发现目标IP地址不在同一子网内,因此需要通过默认网关进行通信。
  2. ARP请求:主机A会查看是否已经缓存了网关的MAC地址。如果没有,它会发送一个ARP请求广播,询问“谁拥有网关的IP地址Y.Y.Y.Y?”。
  3. 网关响应:局域网内的所有主机都会接收到这个ARP请求,只有网关会回应其MAC地址。
  4. 发送数据包到网关:一旦主机A获得了网关的MAC地址,它就可以将数据包发送到网关。
  5. 数据包转发:网关接收到数据包后,会根据其路由表将数据包转发到目标子网
  6. 目标子网的ARP解析:在目标子网内,网关会使用ARP请求来找到主机C的MAC地址,然后将数据包转发给主机

8.3 DHCP

DHCP 在生活中我们是很常见的了,我们的电脑通常都是通过 DHCP 动态获取 IP 地址,大大省去了配 IP 信息繁琐的过程。

image-20250120114150316

  • 客户端首先发起 DHCP 发现报文(DHCP DISCOVER) 的 IP 数据报,由于客户端没有 IP 地址,也不知道 DHCP 服务器的地址,所以使用的是 UDP 广播通信,其使用的广播目的地址是 255.255.255.255(端口 67) 并且使用 0.0.0.0(端口 68) 作为源 IP 地址。DHCP 客户端将该 IP 数据报传递给链路层,链路层然后将帧广播到所有的网络中设备。
  • DHCP 服务器收到 DHCP 发现报文时,用 DHCP 提供报文(DHCP OFFER) 向客户端做出响应。该报文仍然使用 IP 广播地址 255.255.255.255,该报文信息携带服务器提供可租约的 IP 地址、子网掩码、默认网关、DNS 服务器以及 IP 地址租用期
  • 客户端收到一个或多个服务器的 DHCP 提供报文后,从中选择一个服务器,并向选中的服务器发送 DHCP 请求报文(DHCP REQUEST进行响应,回显配置的参数。
  • 最后,服务端用 DHCP ACK 报文对 DHCP 请求报文进行响应,应答所要求的参数。

一旦客户端收到 DHCP ACK 后,交互便完成了,并且客户端能够在租用期内使用 DHCP 服务器分配的 IP 地址。

如果租约的 DHCP IP 地址快期后,客户端会向服务器发送 DHCP 请求报文:

  • 服务器如果同意继续租用,则用 DHCP ACK 报文进行应答,客户端就会延长租期。
  • 服务器如果不同意继续租用,则用 DHCP NACK 报文,客户端就要停止使用租约的 IP 地址。

可以发现,DHCP 交互中,全程都是使用 UDP 广播通信

咦,用的是广播,那如果 DHCP 服务器和客户端不是在同一个局域网内,路由器又不会转发广播包,那不是每个网络都要配一个 DHCP 服务器?

image-20250120114237383

8.4 NAT

NAT 就是同个公司、家庭、教室内的主机对外部通信时,把私有 IP 地址转换成公有 IP 地址。

image-20250120114548270

特殊的:可以解决IPv4短缺,但NAT在某种程度上确实影响了TCP的端到端原则,并且需要转换ip增加了开销。

image-20250120114631312

8.5 ICMP

Internet Control Message Protocol,也就是互联网控制报文协议

当数据包在传输过程中出现问题时,ICMP可以向源主机发送错误消息。例如,如果目标主机不可达,路由器可以发送一个“目的不可达”消息给源主机

image-20250120115449966

ICMP消息被封装在IP数据包中。工作在网络层

image-20250120115523509

9. PING工作原理

ping 是基于 ICMP 协议工作的

image-20250120135353581

Copyright © 版权信息 all right reserved,powered by aspire-zero and Gitbook该文件修订时间: 2025-02-26 19:31:48

results matching ""

    No results matching ""