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

1. Linux 网络路径
理解 Linux网络栈(1):Linux 网络协议栈简单总结文章插图
1.1 发送端1.1.1 应用层
(1) Socket
应用层的各种网络应用程序基本上都是通过 Linux Socket 编程接口来和内核空间的网络协议栈通信的 。 Linux Socket 是从 BSD Socket 发展而来的 , 它是 Linux 操作系统的重要组成部分之一 , 它是网络应用程序的基础 。 从层次上来说 , 它位于应用层 , 是操作系统为应用程序员提供的 API , 通过它 , 应用程序可以访问传输层协议 。

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

理解 Linux网络栈(1):Linux 网络协议栈简单总结文章插图
理解 Linux网络栈(1):Linux 网络协议栈简单总结文章插图
UDP socket 处理过程
理解 Linux网络栈(1):Linux 网络协议栈简单总结文章插图
Linuxc/c++服务器开发高阶视频学习资料后台私信【架构】获取
理解 Linux网络栈(1):Linux 网络协议栈简单总结文章插图
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 网络协议栈简单总结文章插图
1.1.2 传输层
传输层的最终目的是向它的用户提供高效的、可靠的和成本有效的数据传输服务 , 主要功能包括 (1)构造 TCP segment (2)计算 checksum (3)发送回复(ACK)包 (4)滑动窗口(sliding windown)等保证可靠性的操作