最上层的应用程序,需要通过系统调用,来跟套接字接口进行交互;套接字的下面,就是我们前面提到的传输层、网络层和网络接口层;最底层,则是网卡驱动程序以及物理网卡设备。
网卡是发送和接收网络数据包的基本设备。在系统启动时,网卡通过内核中的网卡驱动程序注册到系统中。在网络收发过程中,内核通过中断与网卡进行交互。
结合Linux网络栈,可以看出网络包的处理是非常复杂的。所以网卡的硬中断只处理网卡的核心数据读取或发送,而协议栈中的大部分逻辑会放到软中断中。
【文章福利】C/C Linux服务器架构师需学习资料添加群812855908(资料包括C/C、Linux、golang技术、内核、Nginx、ZeroMQ、MySQL、Redis、fastdfs、MongoDB、ZK、流媒体、CDN、P2P、K8S、Docker、TCP/IP、协议、)
Linux网络发送和接收过程
了解了Linux网络栈之后,我们再来看看Linux是如何收发网络包的。
网络的分组接收过程
我们先来看看网络包的接收过程。
当网络帧到达网卡时,网卡会通过DMA将网络数据包放入数据包接收队列。然后通过硬中断,告诉中断处理程序已经收到网络包。
然后网卡中断处理程序为网络帧分配内核数据结构(sk_buff)并复制到sk_buff缓冲区;然后,使用软中断通知内核已经接收到新的网络帧。
接下来,内核协议栈从缓冲区中取出网络帧,通过网络协议栈自下而上逐层处理网络帧。例如:
在链路层检查报文的合法性,找出上层协议的类型(比如 IPv4 还是 IPv6),再去掉帧头、帧尾,然后交给网络层。网络层取出 IP 头,判断网络包下一步的走向,比如是交给上层处理还是转发。当网络层确认这个包是要发送到本机后,就会取出上层协议的类型(比如CP 还是 UDP),去 掉 IP 头,再交给传输层处理。传输层取出 TCP 头或者 UDP 头后,根据