计算机网络

Mar 08, 2025 12:16 PM
Mar 10, 2025 7:49 AM

尽量保证描写的清楚,且简洁。

TCP/IP 模型

四层:

网络解析网址的方式 :

URL:协议+//+服务器名称+/.../(数据源的路径)


通俗版解析:从输入网址到网页显示的全过程


1. 第一步:浏览器解析网址(找地址)
比喻:就像你想去朋友家,但只知道小区名,不知道具体门牌号。
过程
拆解 URL:浏览器把网址拆成「域名」(如 www.example.com)和「路径」(如 /index.html``)。 • **检查缓存**:先翻自己的「小本本」(浏览器缓存)看有没有记录过这个域名的 IP 地址。 • **问操作系统**:如果小本本没记,就问电脑管家(操作系统):“你记得 www.example.com` 的地址吗?”


2. DNS 查询:全网找门牌号
比喻:打电话问 114 查号台,但需要层层转接。
过程

  1. 本地 DNS 服务器(小区物业):
    ◦ 先查自己的记录,没有就联系上级。
  2. 根 DNS 服务器(全球总台):
    ◦ 回答:“.com 的顶级 DNS 服务器地址是X.X.X.X,你问它。”
  3. 顶级域 DNS(.com 管理局):
    ◦ 回答:“example.com 的权威 DNS 服务器是Y.Y.Y.Y,你问它。”
  4. 权威 DNS 服务器(朋友小区的物业):
    ◦ 最终给出 IP 地址:“门牌号是 93.184.216.34!”
    结果:浏览器拿到 IP 地址,准备出发。

3. 建立 TCP 连接:确认对方在家
比喻:打电话给朋友,先确认他是否在线。
三次握手

  1. 你(客户端):“喂,能听到吗?”(发送 SYN 包)
  2. 朋友(服务器):“能听到,你说话吧!”(回复 SYN-ACK 包)
  3. :“好的,我要说正事了!”(发送 ACK 包)
    结果:连接建立,开始传输数据。

4. 发送 HTTP 请求:打包你的需求
比喻:写一封信,告诉朋友你要借哪本书。
内容
请求行:“GET /index.html HTTP/1.1”(我要首页)
请求头:附加信息(浏览器类型、支持的语言等)。
请求体:如果是登录请求,会包含账号密码。


5. 数据包旅行:跨城快递
比喻:把信交给快递员,经过多个中转站。
过程

  1. 封装成 TCP 包:信纸装进信封(TCP 头部),写上序号(防止丢件)。
  2. 封装成 IP 包:套上快递袋(IP 头部),写清发件人(你的 IP)和收件人(服务器 IP)。
  3. MAC 地址定位:快递员(交换机)根据门牌号(MAC 地址)送到小区门口。
  4. 路由器接力
    ◦ 小区门口快递站(路由器)检查地址:“这封信要跨省,先送到省中心!”
    ◦ 省中心再转发到目标城市,直到抵达朋友家。

6. 服务器处理:拆信并回信
比喻:朋友收到信,找到书后回寄给你。
过程
拆包:服务器一层层剥开 IP、TCP 头部,看到 HTTP 请求。
处理请求:读取 /index.html,从硬盘找到文件。
生成响应:把 HTML 内容塞进 HTTP 响应包,反向封装(TCP→IP→MAC)。
回传:按原路返回,经过路由器、交换机,最终到你的电脑。


7. 浏览器渲染:拆包裹拼图
比喻:收到回信后,把碎片拼成完整的画。
过程
接收数据包:按 TCP 序号重组文件。
解析 HTML:读取文本、图片、CSS 样式。
渲染页面:把代码变成你看到的按钮、文字、图片。


关键概念通俗解析

术语 通俗解释 类比
DNS 把网站名翻译成数字地址的电话簿 查号台(114)
TCP 确保数据完整送达的“快递保价服务” 快递员打电话确认你收到包裹
IP 地址 设备的全球唯一“门牌号” 家庭住址(XX 省 XX 市 XX 街道)
MAC 地址 设备的“身份证号”,用于同一网络内精准定位 快递柜编号(A 区 3 号柜)
路由器 跨网络转发数据的“中转站” 跨省快递分拣中心
交换机 同一网络内转发数据的“快递柜” 小区内的快递代收点

Linux 网络包收发机制

一、网络模型基础

  1. OSI 七层模型(理论模型):
    • 应用层(用户接口)
    • 表示层(数据格式转换)
    • 会话层(建立/管理连接)
    • 传输层(端到端传输)
    • 网络层(路由和寻址)
    • 数据链路层(物理寻址)
    • 物理层(比特流传输)

  2. TCP/IP 四层模型(实际实现):
    • 应用层(HTTP/FTP/DNS 等)
    • 传输层(TCP/UDP)
    • 网络层(IP/ICMP)
    • 网络接口层(以太网/WiFi)

关键区别:TCP/IP 模型将 OSI 的上三层合并为应用层,更注重实用性。Linux 系统采用 TCP/IP 模型实现。

二、数据封装过程(发送时)
以发送"Hello"字符串为例:

应用层:原始数据 "Hello"
↓ 添加TCP头(源/目标端口、序列号等)
传输层:[TCP头]+"Hello"
↓ 添加IP头(源/目标IP地址)
网络层:[IP头]+[TCP头]+"Hello"
↓ 添加帧头帧尾(MAC地址、CRC校验)
网络接口层:[帧头]+[IP头]+[TCP头]+"Hello"+[帧尾]

三、接收网络包流程

  1. 硬件接收阶段
    • 网卡通过 DMA 将数据包存入环形缓冲区(Ring Buffer)
    • 触发硬件中断通知 CPU

  2. 中断处理优化(NAPI 机制)
    • 传统方式:每个包都触发中断 → 高负载时 CPU 被频繁打断
    • NAPI 方案:
    ◦ 首次中断唤醒处理线程
    ◦ 后续采用轮询方式批量处理多个数据包
    ◦ 减少中断次数,提升吞吐量

  3. 协议栈处理

  4. 关键数据结构
    sk_buff:贯穿整个协议栈的核心数据结构
    • 通过指针调整实现零拷贝:

    struct sk_buff {
        unsigned char *head; // 缓冲区起始
        unsigned char *data; // 当前协议层起始
        unsigned char *tail; // 数据结束
        unsigned char *end;  // 缓冲区结束
    };
    

四、发送网络包流程

  1. 应用层发起

    send(socket_fd, buffer, len, 0); // 系统调用
    
  2. 内核处理过程
    • 创建 sk_buff 并拷贝用户数据
    • 逐层添加协议头:

    graph LR
    A[应用数据] --> B[添加TCP头]
    B --> C[添加IP头]
    C --> D[添加帧头帧尾]
  3. TCP 重传机制
    • 克隆 sk_buff 副本发送
    • 原始包保留直到收到 ACK
    • 实现可靠传输的核心机制

  4. 分片处理(MTU 限制)
    • 当 IP 包超过 1500 字节时:

    def fragment(packet):
        chunks = []
        while len(packet) > MTU:
            chunk = packet[:MTU-20]  # 保留IP头空间
            chunks.append(add_ip_header(chunk))
            packet = packet[MTU-20:]
        chunks.append(add_ip_header(packet))
        return chunks
    

五、关键性能优化点

  1. 零拷贝技术
    • sendfile 系统调用:文件→Socket 直接传输
    • 减少用户态与内核态数据拷贝

  2. 多队列网卡
    • 每个 CPU 核心绑定独立队列
    • 避免缓存行竞争

  3. TSO/GSO
    • TCP Segmentation Offload:网卡硬件分片
    • Generic Segmentation Offload:内核延迟分片

六、完整流程对比

接收流程 发送流程
1. 网卡 DMA 到 Ring Buffer 1. 应用调用 send()
2. 触发硬中断 2. 创建 sk_buff 并拷贝数据
3. ksoftirqd 软中断处理 3. 协议栈逐层封装
4. 协议栈逐层解析 4. 分片处理(如果需要)
5. 数据存入 Socket 缓冲区 5. ARP 查询下一跳 MAC
6. 应用 read()读取 6. 网卡 DMA 发送

七、常见问题解答
Q:为什么需要三次内存拷贝?
A:发送时的三次拷贝:

  1. 用户空间→内核 sk_buff
  2. TCP 重传保留副本
  3. IP 分片时产生新副本

Q:MTU 设置 1500 字节的历史原因?
A:源自早期以太网的电气特性限制,现代网络可通过 Jumbo Frame(9000 字节)提升吞吐量。

Q:如何查看协议栈统计?

netstat -s       # 统计摘要
ethtool -S eth0  # 网卡详细统计
cat /proc/net/softnet_stat # 软中断统计

HTTP