本文是在阅读JavaGuide关于计算机网络相关内容时的个人整理;

请移步:https://javaguide.cn/cs-basics/network/osi-and-tcp-ip-model.html

OSI七层模型

很清晰、理论完整,但是太复杂且不适用,所以更多使用tcp/ip协议

  1. 应用层:为用户提供了与网络进行交互的接口;
  2. 表示层:进行一些数据处理,例如加密解密、编码解码、压缩和解压缩
  3. 会话层:管理应用程序之间的会话
  4. 传输层:为会话之间的通信提供可靠的数据传输
  5. 网络层:IP数据包在传输时的路由和寻址
  6. 链路层:对数据帧进行编码、对传输的误差进行纠正
  7. 物理层:传输比特流数据

TCP/IP四层模型

应用层

应用层:以报文数据单元,使得应用程序之间进行信息交换

常见协议:

基于TCP

  • HTTP协议(HTTPs):基于 TCP 协议,是一种用于传输超文本和多媒体内容的协议,为 Web 浏览器与 Web 服务器之间的通信而设计的
  • Websocket协议:客户端和服务端可以同时发送或接收,基于 TCP 连接的全双工通信,通过心跳机制来保持 WebSocket 连接的稳定性和活跃性
  • SMTP协议(简单邮件传输(发送)协议)、IMAP/POP3协议(负责邮件接收的协议)
  • FTP协议:文件传输,使用两条tcp连接,一条用于传输控制信息,一条用于数据传送;不安全,SFTP安全
  • SSH协议:通过加密认证机制实现安全的访问和文件传输等业务;Telnet协议:用于终端登录服务器,明文传输不安全

基于UDP

  • RTP协议⚠️、WebRTC⚠️

传输层

传输层:负责向两台终端设备进程之间的通信提供通用的数据传输服务

TCP协议的三次握手和四次挥手:面向连接的、可靠的

UDP协议:无连接的、尽力的

网络层

网络层:网络层负责为分组交换网上的不同主机提供通信服务

封装成IP数据包,解析IP地址,选择合适的路由

常见协议:IP协议(定义数据包的格式、对数据包进行路由和寻址)、ARP协议(网络层地址和链路层地址之间的转换问题)、NAT协议(网络地址转换,内部网到外部网)、ICMP协议⚠️、OSPF协议⚠️、RIP协议⚠️

网络接口层

网络接口层:把IP数据包组装成帧,并在相邻计算机节点之间传输比特流,并提供差错检测和修复等等

HTTP相关

HTTP1.0和1.1

  1. 缓存:见缓存
  2. 长连接和短连接:HTTP1.0使用短连接,每次HTTP操作都需要建立tcp连接,会导致握手挥手报文大量占据带宽;长连接可以设置超时时间,减少保持tcp连接的资源浪费。
  3. Host头处理⚠️
  4. 带宽优化:加入Range头部,可以请求**数据(只能是字节型)**的一部分,支持断点续传,例如下载文件到一半
1
2
3
4
5
6
7
8
9
10
11
# 请求:获取一个文件的前 1024 个字节
GET /z4d4kWk.jpg HTTP/1.1
Host: i.imgur.com
Range: bytes=0-1023

# 相应:206状态码
HTTP/1.1 206 Partial Content
Content-Range: bytes 0-1023/146515
Content-Length: 1024

(二进制内容)

HTTP和HTTPS

  1. HTTP(明文传输, 没有状态):默认端口80,规范浏览器和服务器端的行为。传输的都是明文,不安全。

    无状态(stateless)协议,服务器不维护任何有关客户端过去所发请求的消息,有状态协议会更加复杂,需要维护状态(历史信息),而且如果客户或服务器失效,会产生状态的不一致,解决这种不一致的代价更高。

  2. HTTPS(加密传输, 证书认证):默认端口号是 443。额外使用 SSL/TLS 协议用作加密和安全认证。

先使用非对称加密传输对称加密的密钥,来保证密钥的安全性;再进行对称加密的通信。

可能会存在以下使用诈包的攻击手段,所以服务器得进行第三方实名认证,这个就是证书(CA, Certificate Authority)的作用

诈包攻击

图源:JavaGuide

HTTP缓存

强制缓存

强制缓存优先于协商缓存进行

  1. HTTP1.0使用Expires,它存储一个过期时间,如果在这个时间内就说明缓存有效,但是依赖于浏览器时间

  2. HTTP1.1使用cache-control字段,有6个字段,常用的是max-age表示缓存的有效时间,例如Cache-Control: max-age=10

cache-control字段:

  • max-age决定客户端资源被缓存多久。
  • s-maxage决定代理服务器缓存的时长。
  • no-cache表示是强制进行协商缓存。
  • no-store是表示禁止任何缓存策略。
  • public表示资源即可以被浏览器缓存也可以被代理服务器缓存。
  • private表示资源只能被浏览器缓存。

协商缓存

需要向服务器发起请求进行协商,由服务器决定是否使用缓存

  1. HTTP1.0使用Last-Modified / If-Modified-Since

If-Modified-Since是客户端再次发起该请求时,携带上次请求返回的Last-Modified值,通过此字段值告诉服务器该资源上次请求返回的最后被修改时间。服务器收到该请求,发现请求头含有If-Modified-Since字段,则会根据If-Modified-Since的字段值与该资源在服务器的最后被修改时间做对比,若服务器的资源最后被修改时间大于If-Modified-Since的字段值,则重新返回资源,状态码为200;否则则返回304,代表资源无更新,可继续使用缓存文件;

  1. HTTP1.1使用Etag / If-None-Match

If-None-Match是客户端再次发起该请求时,携带上次请求返回的唯一标识Etag值,通过此字段值告诉服务器该资源上次请求返回的唯一标识值。服务器收到该请求后,发现该请求头中含有If-None-Match,则会根据If-None-Match的字段值与该资源在服务器的Etag值做对比,一致则返回304,代表资源无更新,继续使用缓存文件;不一致则重新返回资源文件,状态码为200;

常见状态码

  1. 1xx(临时响应):表示临时响应并需要请求者继续执行操作的状态码。

101:切换协议,切换到更高级的协议,例如HTTP新版

  1. 2xx(成功):表示成功处理了请求的状态码。

201:请求成功创建一个或多个新的资源

204:请求成功,但没有结果返回(不看重请求结果,只关心是否完成)

206:请求一部分资源,成功响应一部分资源(HTTP1.1断点续传)

  1. 3xx(重定向):要完成请求,需要进一步操作。通常,这些状态码用来重定向。

301:Moved Permanently,资源被永久重定向。比如网站的网址被更换。

  1. 4xx(客户端请求错误)

400 Bad Request:发送的 HTTP 请求存在问题。比如请求参数不合法、请求方法错误。

401 Unauthorized:未认证却请求需要认证之后才能访问的资源。

403 Forbidden:直接拒绝 HTTP 请求,不处理。一般用来针对非法请求。

404 Not Found:你请求的资源未在服务端找到。比如你请求某个用户的信息,服务端并没有找到指定的用户。

409 Conflict:表示请求的资源与服务端当前的状态存在冲突,请求无法被处理。

  1. 5xx(服务器错误)

500 Internal Server Error:服务端出问题了(通常是服务端出 Bug 了)。比如你服务端处理请求的时候突然抛出异常,但是异常并未在服务端被正确处理。

502 Bad Gateway:我们的网关将请求转发到服务端,但是服务端返回的却是一个错误的响应,即网关正常运行,但是网关得到的响应是错误的。

TCP相关

可靠性保证

  1. 基于数据块传输:分割成数据块(报文段)再给网络层,网络层也可能进一步分割再形成ip数据包;
  2. 报文段序列号可以用来重新排序和去重;
  3. 报文段包含首部数据,接收后会进行校验和,确保数据没有发生差错;
  4. 流量控制和拥塞控制

访问网页的全过程

  1. DNS解析,得到IP地址
  2. 根据IP地址建立TCP连接
  3. 在TCP连接上发送HTTP请求报文
  4. 服务器处理请求,返回HTTP响应
  5. 解析响应体中HTML代码并渲染
  6. 对HTML中其他需要的资源再次发起请求
  7. 可以主动关闭TCP连接,或等待服务器关闭

ARQ协议

  1. 停止等待ARQ协议(这个没有用到滑动窗口协议)

每发完一个数据包就停止发送,等待对方确认(回复 ACK);如果过了一段时间(超时时间后),还是没有收到 ACK 确认,说明没有发送成功,需要重新发送,直到收到确认后再发下一个数据包。

1.1. 发送的数据包丢了:设置一个定时器,自动重传;

1.2. 确认信息丢了or迟到:发送方没收到确认信息,重传,重复的信息直接丢弃。


  1. 连续ARQ协议(引入滑动窗口),位于发送窗口内的分组可以连续发送出去,而不需要等待对方确认。

2.1. 接收方累计确认(对最后一个数据包发送确认),信道利用率高;

2.2. 滑动窗口中间某个丢了,需要把丢失的后续都传一遍,即Go-Back-N。

重传机制

⚠️参考:知乎专栏

流量控制

  • 为了控制发送方发送速率,接收方来得及接收和处理;客户端和服务端各自维护发送窗口和接收窗口

  • 滑动窗口:针对报文段的划分方式,大小是根据接收端处理数据的速度动态调整的;tcp三次握手的时候会协调出窗口的大小

为什么这种机制能做到流量控制?为发送和确认的异步性提供了缓冲(又快又慢)

  1. 快:不仅得发送,还得确认接受,这样就不用阻塞在等待确认上了,可以先发送多个然后一起等待确认;
  2. 慢:如果一直不确认累积一定数目,就会不发送;只有确认才能让滑动窗口移动;

滑动窗口

图源:JavaGuide

拥塞控制

防止过多的数据注入到网络中,维护一个拥塞窗口cwnd,在实际使用中会选取滑动窗口和拥塞窗口的最小值

慢开始和拥塞避免

tcp协议在一开始发送数据时,会让拥塞窗口从小到大倍数增长,即每经过一个传播轮次RTT,cwnd加倍;

但是后续不可能增大这么快,所以等到达阈值后,会使用每经过一个传播轮次RTT,cwnd+1的方式;

快重传和快恢复

FRR-fast retransmit and recovery

  1. 如果没有 FRR,当数据包丢失了,TCP 将会使用定时器来要求传输暂停。在暂停的这段时间内,没有新的或复制的数据包被发送。
  2. 有了 FRR,当接收机接收到一个不按顺序的数据段(例如接收了1 3),它会立即给发送机发送一个重复确认(此时依然正常接收其他数据包,例如接收1 3 4)。如果发送机接收到三个重复确认(如果是1个,可能把网络延迟给误判成丢包了),它会假定确认件指出的数据段丢失了,并立即重传这些丢失的数据段。
  3. 快重传:指接收方接收到三个重复确认,此时立即重传对应序列的报文段;
  4. 快恢复:发生快重传时,把阈值ssthresh、拥塞窗口cwnd都缩小到当前cwnd的一半,并切换到拥塞避免算法(每经过一个传播轮次RTT,cwnd+1)

image-20250111181016426

图源:王道考研

三次握手

先总说:1. 客户端发送数据包等待服务端确认,2. 服务端确认的同时,也需要客户端确认能否收到自己的数据;3. 客户端确认能收到服务端的数据

  • 第一次握手,发送端首先发送一个带SYN(synchronize)标志的数据包给接收方,第一次的seq序列号是随机产生的,这样是为了网络安全,如果不是随机产生初始序列号,黑客将会以很容易的方式获取到你与其他主机之间的初始化序列号,并且伪造序列号进行攻击

  • 第二次握手,接收端收到后,回传一个带有SYN/ACK(acknowledgement)标志的数据包以示传达确认信息;SYN 是为了告诉发送端,发送方到接收方的通道没问题;ACK 用来验证接收方到发送方的通道没问题

  • 第三次握手,发送端再回传一个带ACK标志的数据包,代表握手结束,若在握手某个过程中某个阶段莫名中断,TCP协议会再次以相同的顺序发送相同的数据包

三次握手

图源:稀土掘金

四次挥手

  • 客户端发送一个 FIN,用来关闭服务端到客户端的数据传送

  • 服务端收到这个 FIN,它发回一个 ACK,确认序号为收到的序号加1 。和 SYN 一样,一个 FIN 将占用一个序号

  • 服务端关闭与客户端的连接,发送一个FIN给客户端

  • 客户端发回 ACK 报文确认,并将确认序号设置为收到序号加1

四次挥手

图源:稀土掘金

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

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