1. 网络模型

1.1 OSI网络模型

  • 应用层
  • 表示层
  • 会话层
  • 传输层
  • 网络层
  • 数据链路层
  • 物理层

1.2 TCP/IP网络模型

  • 应用层,负责向用户提供一组应用程序
  • 传输层,负责端到端的通信
  • 网络层,负责网络包的封装
  • 网络接口层,负责网络包在物理网络的传输

2. Linux网络栈

c5360203b333426806cbe9e3abbfb5b2.png

3. Linux网络收发流程

3.1 网络包的接收流程

  1. 当一个网络帧到达网卡后,网卡会通过DMA方式,把网络包放在收放队列中;然后通过硬中断,告诉中断处理程序已经收到网络包
  2. 网卡中断处理程序会为网络帧分配内核数据结构,并将其拷贝到sk_buff缓冲区中,通知内核收到新的网络帧
  3. 内核协议栈从缓冲区中取出网络帧,并通过网络帧协议,从下到上处理网络帧
  4. 链路层检查报文的合法性,找到上层协议类型,去掉帧头、帧尾
  5. 网络层取出ip头,判断网络包下一步的走向,比如交给上层处理还是转发。但确认网络层这个包是要发送到本机,就会去掉ip头,再提交传输层
  6. 传输层取出TCP或UDP头后,根据<源IP、源端口、目的IP、目的端口>四元组为标识,找到对应的socket,并把数据拷贝到socket的接收缓存中 f84c6d24d7ccaf98638d1b749d462180.png

3.2 网络包的发送流程

  1. 首先,应用程序调用socket API发送网络包(这是一个系统调用,所以会陷入到内核态的套接字层中。套接字层会把数据包放到socket发送缓冲区中)
  2. 网络协议栈从socket发送缓冲区中,取出数据包;再按照TCP/IP栈,从上到下逐层处理
  3. 分片后的网络包,再发送到网络接口,进行物理地址寻址,以找到下一个的MAC地址。然后添加帧头和帧尾,放到发包队列中。这一切完成后,会有软中断通知驱动程序:发包队列中有新的网络帧需要发送。
  4. 驱动程序通过 DMA ,从发包队列中读出网络帧,并通过物理网卡把它发送出去。