Skip to content

网络协议

数据传输过程:

  1. 应用层对请求数据包做格式定义
  2. 传输层加端口号,确认应用程序
  3. 网络层加双方IP,确认网络位置
  4. 链路层加双方MAC地址,确认物理位置。将数据分组,形成数据帧并转发给目标主机。

TCP:面向连接的可靠协议
UDP:面向无连接的协议

TCP

TCP报文

  • seq:数据序号,存储本报文段所发送数据的第一个字节的序号
  • ack:确认序号,期望收到对方的下一个报文段的数据的第一个字节的序号
  • ACK:确认标志位,当 ACK=1 时,确认序号才有效
  • SYN:同步标志位,表示这个报文是一个连接请求还是一个连接接受的请求
  • FIN:结束标志位,当 FIN=1 时,表示此报文段的发送端的数据已经发送完成,并且要求释放连接

三次握手:

Alt text

四次挥手: Alt text

问题:为什么TCP客户端最后发送释放确认报文后还要再等待2MSL?
因为客户端无法确认TCP服务器是否收到了报文,如果TCP服务器没有收到就会重发连接释放的报文,则客户进程会再次发送确认报文。如果两倍MSL时间内都没有重新收到TCP服务器的连接释放报文,那么客户端推断确认报文已经被服务端成功接受,从而关闭连接。

HTTP

HTTP请求响应模型:

  1. 建立TCP连接
  2. 客户端向服务器发送请求命令
  3. 客户端发送请求头信息
  4. 客户端发送空行,表示结束请求头信息的发送
  5. 服务器应答
  6. 服务器返回响应头信息
  7. 服务端向客户端发送数据
  8. 服务器关闭TCP连接

如果客户端频繁发送HTTP请求,会导致TCP连接频繁的建立和关闭。因此在需要频繁发送HTTP请求时,请求头可以带上 Connection: keep-alive 保持持久连接。HTTP1.1版本之后默认都是持久连接。

HTTP的相关特性:

  1. HTTP是无状态的的协议。可以引入 Cookie 和 Session 技术管理状态。
  2. HTTP使用 Cookie 来进行客户端的状态管理。服务器响应时通过添加头信息 Set-Cookie: xxx 通知客户端保存该 Cookie 信息,下次客户端发送请求时就会带上 Cookie 信息。
  3. 管线化访问。一个请求没有响应也能发送下一个请求,可以并行发送多个请求。

请求报文:

HTTP
// 请求行
GET /notes/protocol.html HTTP/1.1   # 请求方式 资源路径 协议版本
// 请求头
Accept: text/html;q=0.9             # 可接受的数据类型
Accept-Encoding: gzip, deflate, br  # 可接受的压缩格式
Accept-Language: en-US,en;q=0.9     # 可接受的语言
Connection: keep-alive              # 保持长连接
Host: localhost:5173                # 服务器主机地址和端口号,默认 80
Upgrade-Insecure-Requests: 1        # 让浏览器升级不安全请求,使用 https 请求
User-Agent: Edg/120.0.0.0           # 用户代理
// 空行

// 请求体,POST请求才有,GET没有
username=zhh&password=666

响应报文:

HTTP
// 响应行/状态行
HTTP/1.1 200 OK                      # 协议版本 状态码 状态描述
// 响应头
Content-Type: text/html              # 内容类型
Date: Wed, 03 Jan 2024 18:05:56 GMT  # 服务器响应时间
Connection: keep-alive               # 保持长连接
// 空行

// 响应体
<!DOCTYPE html><html>...</html>