理解 Linux 网络栈(1):Linux 网络协议栈简单总结

1. Linux 网络路径


理解 Linux 网络栈(1):Linux 网络协议栈简单总结_第1张图片

1.1 发送端

1.1.1 应用层

(1) Socket

应用层的各种网络应用程序基本上都是通过 Linux Socket 编程接口来和内核空间的网络协议栈通信的。Linux Socket 是从 BSD Socket 发展而来的,它是 Linux 操作系统的重要组成部分之一,它是网络应用程序的基础。从层次上来说,它位于应用层,是操作系统为应用程序员提供的 API,通过它,应用程序可以访问传输层协议。

  • socket 位于传输层协议之上,屏蔽了不同网络协议之间的差异
  • socket 是网络编程的入口,它提供了大量的系统调用,构成了网络程序的主体
  • 在Linux系统中,socket 属于文件系统的一部分,网络通信可以被看作是对文件的读取,使得我们对网络的控制和对文件的控制一样方便。

理解 Linux 网络栈(1):Linux 网络协议栈简单总结_第2张图片

理解 Linux 网络栈(1):Linux 网络协议栈简单总结_第3张图片

UDP socket 处理过程

理解 Linux 网络栈(1):Linux 网络协议栈简单总结_第4张图片

TCP Socket 处理过程

(2) 应用层处理流程

  1. 网络应用调用Socket API socket (int family, int type, int protocol) 创建一个 socket,该调用最终会调用 Linux system call socket() ,并最终调用 Linux Kernel 的 sock_create() 方法。该方法返回被创建好了的那个 socket 的 file descriptor。对于每一个 userspace 网络应用创建的 socket,在内核中都有一个对应的 struct socket和 struct sock。其中,struct sock 有三个队列(queue),分别是 rx , tx 和 err,在 sock 结构被初始化的时候,这些缓冲队列也被初始化完成;在收据收发过程中,每个 queue 中保存要发送或者接受的每个 packet 对应的 Linux 网络栈 sk_buffer 数据结构的实例 skb。

  2. 对于 TCP socket 来说,应用调用 connect()API ,使得客户端和服务器端通过该 socket 建立一个虚拟连接。在此过程中,TCP 协议栈通过三次握手会建立 TCP 连接。默认地,该 API 会等到 TCP 握手完成连接建立后才返回。在建立连接的过程中的一个重要步骤是,确定双方使用的 Maxium Segemet Size (MSS)。因为 UDP 是面向无连接的协议,因此它是不需要该步骤的。

  3. 应用调用 Linux Socket 的 send 或者 write API 来发出一个 message 给接收端

  4. sock_sendmsg 被调用,它使用 socket descriptor 获取 sock struct,创建 message header 和 socket control message

  5. _sock_sendmsg 被调用,根据 socket 的协议类型,调用相应协议的发送函数。

  6. 对于 TCP ,调用 tcp_sendmsg 函数。
  7. 对于 UDP 来说,userspace 应用可以调用 send()/sendto()/sendmsg() 三个 system call 中的任意一个来发送 UDP message,它们最终都会调用内核中的 udp_sendmsg() 函数。

理解 Linux 网络栈(1):Linux 网络协议栈简单总结_第5张图片

1.1.2 传输层

传输层的最终目的是向它的用户提供高效的、可靠的和成本有效的数据传输服务,主要功能包括
(1)构造 TCP segment
(2)计算 checksum
(3)发送回复(ACK)包
(4)滑动窗口(sliding windown)等保证可靠性的操作

TCP 协议栈的大致处理过程如下图所示:

理解 Linux 网络栈(1):Linux 网络协议栈简单总结_第6张图片

TCP 栈简要过程:

  1. tcp_sendmsg 函数会首先检查已经建立的 TCP connection 的状态,然后获取该连接的 MSS,开始 segement 发送流程。
  2. 构造 TCP 段的 playload:它在内核空间中创建该 packet 的 sk_buffer 数据结构的实例 skb,从 userspace buffer 中拷贝 packet 的数据到 skb 的 buffer。
  3. 构造 TCP header。
  4. 计算 TCP 校验和(checksum)和 顺序号 (sequence number)。
    1. TCP 校验和是一个端到端的校验和,由发送端计算,然后由接收端验证。其目的是为了发现TCP首部和数据在发送端到接收端之间发生的任何改动。如果接收方检测到校验和有差错,则TCP段会被直接丢弃。TCP校验和覆盖 TCP 首部和 TCP 数据。
    2. TCP的校验和是必需的
  5. 发到 IP 层处理:调用 IP handler 句柄 ip_queue_xmit,将 skb 传入 IP 处理流程。

UDP 栈简要过程:

  1. UDP 将 message 封装成 UDP 数据报

你可能感兴趣的:(网络,协议,linux,栈)