|
前篇已经分析了Linux内核中网络栈的初始化过程,下面由卓跃教育为您介绍Linux内核数据包的传递过程。
1、网络接口层
*硬件监听物理介质,进行数据的接收,当接收的数据填满了缓冲区,硬件就会产生中断,中断产生后,系统会转向中断服务子程序。
*在中断服务子程序中,数据会从硬件的缓冲区复制到内核的空间缓冲区,并包装成一个数据结构(sk_buff),然后调用对驱动层的接口函数netif_rx()将数据包发送给链路层。该函数的实现在net/inet/dev.c中,(在整个网络栈实现中dev.c文件的作用重大,它衔接了其下的驱动层和其上的网络层,可以称它为链路层模块的实现)。
2、网络层
*就以IP数据包为例来说明,那么从链路层向网络层传递时将调用ip_rcv函数。该函数完成本层的处理后会根据IP首部中使用的传输层协议来调用相应协议的处理函数。
UDP对应udp_rcv、TCP对应tcp_rcv、ICMP对应icmp_rcv、IGMP对应igmp_rcv(虽然这里的ICMP,IGMP一般成为网络层协议,但是实际上他们都封装在IP协议里面,作为传输层对待)
3、传输层
如果在IP数据报的首部标明的是使用TCP传输数据,则在上述函数中会调用tcp_rcv函数。该函数的大体处理流程为:“所有使用TCP协议的套接字对应sock结构都被挂入tcp_prot全局变量表示的proto结构之sock_array数组中,采用以本地端口号为索引的插入方式,所以当tcp_rcv函数接收到一个数据包,在完成必要的检查和处理后,其将以TCP协议首部中目的端口号(对于一个接收的数据包而言,其目的端口号就是本地所使用的端口号)为索引,在tcp_prot对应sock结构之sock_array数组中得到正确的sock结构队列,在辅之以其他条件遍历该队列进行对应sock结构的查询,在得到匹配的sock结构后,将数据包挂入该sock结构中的缓存队列中(由sock结构中receive_queue字段指向),从而完成数据包的最终接收。”
您有任何关于Linux的疑问,欢迎咨询在线老师
4、应用层
当用户需要接收数据时,首先根据文件描述符inode得到socket结构和sock结构,然后从sock结构中指向的队列recieve_queue中读取数据包,将数据包COPY到用户空间缓冲区。数据就完整的从硬件中传输到用户空间。这样也完成了一次完整的从下到上的传输。
通过上文,您对Linux是否有了一定的了解。如果您还有任何Linux方面的疑问,可以登录www.51great.org,点击在线咨询与在线老师交流。您也可以拨打我们的全国免费咨询专线:0591-83713060进行咨询。
|
|