[图解linux][Network stack系列]:网络包到应用的数据流

在这里插入图片描述

网卡到协议栈边界发生的事情:

在这里插入图片描述

数据包的接受过程

数据包的接收,从下往上经过了三层:网卡驱动、系统内核空间,最后到用户态空间的应用。
现在来详细解释下:

  • 当一个新的数据包到达,NIC(network interface controller)调用 DMA engine,通过Ring Buffer将数据包放置到内核内存区。
  • 一旦数据包被成功接收,NIC发起中断,由内核的中断处理程序将数据包传递给IP层。
  • 经过IP层的处理,数据包被放入队列等待TCP层处理。每个数据包经过TCP层一系列复杂的步骤,更新TCP状态机,
  • 最后到达 recv Buffer,等待被应用接收处理。

我现在解释几点:

  • Linux内核使用 sk_buff(socket kernel buffers)数据结构描述一个数据包。
  • Ring Buffer的大小固定,它不包含实际的数据包,而是包含了指向sk_buff的描述符。当Ring ``Buffer满的时候,新来的数据包将给丢弃。
  • NIC 中内存的 package 数据可以不经过 CPU直接拷贝到Kernel中的内存,这个过程就是
    DMADirectional Memory Access,主要用于快速数据交换。
  • 从上图中可以看到 DMA操作了 kernel 中的一块内存,这块内存其实是 Device Driver 注册的时候向Kernel提前申请的。
  • 最后需要注意,数据包到达 recv BufferTCP就会回ACK确认,既TCPACK表示数据包已经被操作系统内核收到,但并不确保应用层一定收到数据(例如这个时候系统crash),因此一般建议应用协议层也要设计自己的确认机制。

数据包的发送过程

上图中红色的线条表示发送数据包的过程,和接收数据的路径相反,数据包的发送从上往下也经过了三层:用户态空间的应用、系统内核空间、最后到网卡驱动。

  • 应用先将数据写入TCP send bufferTCP层将send buffer中的数据构建成数据包转交给IP层。
  • IP层会将待发送的数据包放入队列 QDisc(queueing discipline)。
  • 数据包成功放入QDisc后,指向数据包的描述符sk_buff被放入Ring Buffer输出队列,随后网卡驱动调用DMA engine将数据发送到网络链路上。

猜你喜欢

转载自blog.csdn.net/qq_33487044/article/details/108137455