2.4 网络概念(分层、TCP)

发布于:2024-12-22 ⋅ 阅读:(12) ⋅ 点赞:(0)

网络层与传输层概述

网络层:
  • 抽象概念:网络层是基于 IP 的抽象概念,与数据链路层用 MAC 地址标记设备不同。MAC 地址是一种具体化的概念,绑定于所在的物理网络,而 IP 地址可以是固定的,也可以通过路由动态变化。
  • 功能:所有“网络”的“网”是基于 IP 的抽象概念,而链路层的“路”是基于 MAC 的具体化概念。
传输层:
  • 协议决定内容:传输层与物理信号的形式(光信号、电信号、无线信号)或目的地无关,传输层的协议决定了传输的内容是可靠的还是不可靠的。例如:
    • 不可靠传输协议:适用于允许丢帧和数据丢失的流媒体传输。
    • 可靠传输协议:适用于需要保密、稳定且不允许数据损坏或丢失的场景,并能控制传输的速度和质量。

数据链路层的作用与网卡驱动

数据链路层的命名

数据链路层之所以称为“链路层”,是因为它负责在物理链路上传输数据。链路指网络中相邻节点之间的物理连接(例如两台计算机或交换机)。

数据链路层的主要作用
  1. 帧的封装和拆解

    • 把网络层的数据打包成帧(Frame)。
    • 在接收端解包帧,提取网络层数据。
  2. 差错检测与纠正

    • 使用校验和机制(如 CRC)检测传输过程中的错误。
    • 部分情况下还能纠正错误。
  3. 流量控制与重传

    • 控制数据流速,防止发送过快导致接收端无法处理。
    • 在数据帧丢失时请求重传。
  4. MAC 地址管理

    • 确保数据在局域网内正确发送到目标设备。
数据链路层与网卡驱动的关系
  • 数据链路层的职责:定义如何在物理链路上传输帧,并确保数据传输的可靠性。
  • 网卡驱动的职责
    • 是数据链路层的一部分。
    • 负责从网卡接收数据并传递给网络层。
    • 与操作系统协作完成数据链路层功能。
数据链路层与网络层的关系
  1. 网络层的职责:负责逻辑寻址和跨网络的数据路由。
  2. 网络层的工作方式
    • 接收来自链路层的帧,解封装出 IP 数据包。
    • 基于 IP 地址和路由信息,将数据传递到目的地。

TCP/IP 协议栈

 tcp组包时 校验和 计算 -- 按照协议中指出,校验和本身在校验时 作为0计算。

校验和前面 还包含了 伪包头 包含了IP地址,是为了防止路由错IP 

主要组成部分
  1. 链路层(Link Layer):对应 OSI 模型中的数据链路层。
  2. 网络层(Internet Layer):主要协议是 IP,负责跨网络的数据路由。
  3. 传输层(Transport Layer):如 TCP 和 UDP,提供端到端的数据传输。
  4. 应用层(Application Layer):处理应用数据和服务,如 HTTP、FTP。
数据包的传递流程
  • 链路层负责在物理网络中传输数据帧。
  • 网络层通过路由实现数据的跨网络传递。
  • 传输层提供可靠或不可靠的数据传输服务。

网卡驱动与 sk_buff 结构体

sk_buff 的作用
  • 是 Linux 内核中描述网络数据包的重要数据结构。
  • 用于存储和管理网络协议栈的所有数据包。
典型的数据包接收流程
  1. 网卡驱动接收数据
    • 网卡驱动接收到数据包后,分配一个 sk_buff
    • 将数据存储到 sk_buff 的缓冲区中。
  2. 传递给协议栈
    • 通过 netif_rx() 等函数将 sk_buff 传递给网络层。
  3. 网络层处理
    • 解封装数据,提取 IP 包进行进一步处理。
sk_buff 的主要字段
  • data:指向数据部分。
  • len:数据长度。
  • protocol:上层协议类型。
  • dev:关联的网络设备。
  • 头部信息指针:mac_headernetwork_headertransport_header
sk_buff 示例
struct sk_buff *skb = netdev_alloc_skb(dev, len);
if (!skb) {
    return -ENOMEM;
}
memcpy(skb_put(skb, len), data, len);
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);

传输层与 TCB 结构体

TCB 的作用
  • **传输控制块(TCB, Transmission Control Block)**用于管理和维护 TCP 连接。
  • 在 Linux 内核中,TCB 主要由 struct tcp_sock 表示。
tcp_sock 定义位置
  • 定义于 include/net/tcp.h
tcp_sock 的主要字段
  • snd_nxt:发送窗口的下一个序列号。
  • rcv_nxt:接收窗口的下一个序列号。
  • snd_una:未被确认的序列号。
  • sk_receive_queue:接收队列。
  • sk_write_queue:发送队列。
tcp_sock 的连接生命周期
  1. 初始化:三次握手时分配并初始化。
  2. 状态更新:更新发送和接收窗口的序列号。
  3. 关闭连接:释放 tcp_sock,完成连接关闭。
传输层的数据流向
  • 发送方向
    • 数据通过 send() 进入传输层,存储到发送缓冲区。
    • 在合适时机发送到网络。
  • 接收方向
    • 数据通过网卡驱动传递到 sk_buff,存储到接收缓冲区。
    • 应用层通过 recv() 获取数据。
tcp_sock 示例
struct tcp_sock {
    __u32 snd_nxt;
    __u32 rcv_nxt;
    __u32 snd_una;
    struct sk_buff_head write_queue;
    struct sk_buff_head receive_queue;
    // 其他状态变量
};

总结

  • 数据链路层处理物理链路上的数据传输,网卡驱动是其一部分。
  • 网络层负责跨网络的数据路由,是 TCP/IP 协议栈的重要组成。
  • sk_buff 是 Linux 内核中描述网络数据包的核心数据结构。
  • tcp_sock 用于管理 TCP 连接,是传输层的重要组件。


传输控制块(TCB)简介

在 Linux 网络协议栈中,传输控制块(TCB, Transmission Control Block) 是用于管理和维护传输层连接的核心数据结构。对于 TCP 协议来说,TCB 主要由 struct tcp_sock 结构体表示,它定义了 TCP 连接的状态和相关的控制信息。


1. struct tcp_sock 的定义位置

tcp_sock 结构体定义在内核代码的 include/net/tcp.h 文件中,是 Linux 内核对 TCP 连接进行管理的主要结构体。


2. tcp_sock 的作用

  • TCP 连接状态信息:保存 TCP 连接的四元组(源 IP、目的 IP、源端口、目的端口)和状态(如 ESTABLISHED, SYN_SENT 等)。
  • 窗口大小与重传信息:用于管理 TCP 滑动窗口大小、重传计时器和拥塞控制。
  • 发送和接收缓冲区:包括发送队列和接收队列,分别存储未发送的数据和已接收但未处理的数据。
  • 序列号管理:跟踪和管理 TCP 的序列号和确认号,以保证数据包的顺序和可靠性。

3. tcp_sock 的主要字段

以下列举了 tcp_sock 中的一些关键字段及其作用:

字段名 作用
rcv_nxt 接收窗口的下一个序列号
snd_nxt 发送窗口的下一个序列号
snd_una 第一个未被确认的字节的序列号
copied_seq 接收队列中已被应用程序读取的字节序列号
write_seq 发送队列中已被写入但未发送的下一个字节序列号
sk_receive_queue 已接收但未处理的数据包队列
sk_write_queue 待发送的数据包队列

4. tcp_sock 的连接生命周期

1. 初始化

当一个新的 TCP 连接建立时,内核会为该连接分配并初始化一个 tcp_sock 结构体,记录四元组并设置初始状态(如 SYN_SENTSYN_RECV)。

2. 状态更新

随着 TCP 三次握手及后续通信的进行,tcp_sock 的状态和字段不断更新。例如:

  • 数据发送时,更新发送窗口中的 snd_nxtsnd_una
  • 数据接收时,更新接收窗口中的 rcv_nxt
3. 关闭连接

TCP 连接关闭时,tcp_sock 状态会更新为 CLOSE_WAITFIN_WAIT,最终释放内存。


5. 从哪里到哪里

1. 发送方向

当应用层调用 send() 时,数据经由套接字接口进入传输层,TCP 层通过 tcp_sendmsg() 处理这些数据,将其存入 tcp_sock 的发送缓冲区,待网卡驱动发送到网络中。

2. 接收方向

当网卡驱动接收到 TCP 数据包后,数据会通过 sk_buff 传递到 TCP 层。TCP 根据数据包的序列号将其存入 tcp_sock 的接收缓冲区,供应用层调用 recv() 获取。


6. 简单示例:tcp_sock 部分定义

以下是 tcp_sock 的简化定义:

struct tcp_sock {
    __u32  snd_nxt;            // 发送窗口的下一个序列号
    __u32  rcv_nxt;            // 接收窗口的下一个序列号
    __u32  snd_una;            // 第一个未被确认的字节的序列号
    struct sk_buff_head  write_queue;  // 待发送的 skb 队列
    struct sk_buff_head  receive_queue; // 已接收但未处理的 skb 队列
    // 其他用于管理 TCP 连接的状态变量
};

总结

  1. TCB(传输控制块) 在 Linux 中主要由 struct tcp_sock 表示,是 TCP 协议管理的核心数据结构。
  2. 它的定义位于 include/net/tcp.h 文件中,保存了 TCP 协议中的关键信息,包括连接状态、序列号、窗口大小、发送与接收队列等。

Sign in · GitLab