注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

逍遥子 曰:

得失失得 何必患得患失 舍得得舍 不妨不舍不得

 
 
 

日志

 
 

[原]TCPIP协议卷2之io中断  

2016-08-05 14:41:39|  分类: 计算机网络 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

一、操作系统关于网络部分的分层处理

操作系统完成用户和物理链路之间的转换,这种转换可简单分为三个层面,如下图所示:

插口层,直接对应用户的系统调用,完成用户调用参数校验等等,它不设计任何网络协议相关的工作;

协议层,完成协议相关的操作,例如将插口层交过来的数据加上tcp/udp和ip层的头部等等。

网络接口层,完成与物理传输媒介的交互,它包括数据链路层和网卡驱动,它一端对接协议层,一端对接物理链路。

[原]TCPIP协议卷2之io中断 - 逍遥子 - 逍遥子 曰:

 

图1

在用户进程发送数据的过程如下:

(1)用户进程调用系统函数sendto,并在参数中指定自己要发送的数据,以及发送的目标地址,这时用户要发送的数据还在用户空间;

(2)在插口层的sendto函数中,做参数校验,并在系统空间申请一块内存,把用户空间的数据复制到内核空间,然后将内核空间的数据转交给下一层协议层。

(3)协议层在拿到内核数据之后,在数据头部加上UDP的首部和IP层的首部,然后将数据交给下面的网络接口层;

(4)网络接口层再加上mac地址,然后通过网卡驱动把数据从网卡发送出去。

用户进程接收数据的过程如下:

(1)网卡驱动通过中断方式从网卡上获取一个数据分组(即来数据时产生一个中断,中断函数由网卡驱动实现,网卡驱动知道怎么从网卡把数据读进来),并将从这个数据分组存储在内核的一个缓冲区中,然后网卡驱动将这个内核缓冲区交给数据链路层来处理;

(2)数据链路层将根据数据帧中的字段判断该数据分组属于哪个协议层,并将内核缓存区交付它对应的队列中,需要注意:[1]数据链路层和上面的网卡驱动都对应上图中的网络接口层;[2]。将数据交给协议层是通过中断来完成的,而不是系统调用。

(3)IP通过中断对一个底层传上来的数据进行IP协议的处理,例如:处理IP层的首部、校验和、IP选项等等;如果当前的主机是路由器,且当前的数据报的地址是非本机地址,则转发这个数据报。IP层通过检查首部的协议字段就可确认当前的数据属于哪个上层协议:1:ICMP协议、2:IGMP协议、6:TCP、17UDP。

(4)TCP/UDP也要进行相应的校验和、协议检查,数据到这里已经知道是属于TCP还是UDP;在《unixt文件描述符——socket》一文中提到,TCP和UDP都有一个属于自己的协议控制块的双向链表,当接收到数据包时,就检查这个协议控制块的双向链表,通过对比数据包的源IP地址、源端口号、目的IP地址和目的端口号这四项与哪个协议控制块对应上,就可以确定当前这个数据是属于哪个协议控制块的。

(5)协议控制块中有个指针指向它所属的socket,数据处理到这里就知道应该交付到哪个socket的接收缓存了,此时,只需要把包含数据的内核缓冲区挂到socket接收缓存链表中既可,不需要进行数据拷贝。

(6)唤醒等待的应用进程;

(7)应用进程读取数据是再将数据从内核缓冲区复制到应用进程指定的用户空间的缓存中。

通过上面收发数据的过程可以看到,在发送数据时,是通过系统调用层层处理将数据发送出去;在接收数据时,是通过层层的中断来处理的,下一层产生一个中断,由上一层来处理这个中断。

二、中断处理

在操作系统对网络数据包进行自底向上传递过程中,需要经历一系列的中断,在操作系统中也是通过中断完成数据的互斥操作。下表是《TCP/IP协议卷2》中提供的8个中断函数和对应的优先级,每个中断处理期间只能被更高优先级的中断打断,不会被同级别或者比自己低级别的中断打断,通过这种方式即可完成中断处理时的互斥操作。

[原]TCPIP协议卷2之io中断 - 逍遥子 - 逍遥子 曰:

 

表1

如下图是中断在处理网络数据时的过程,图中每种颜色代表一个执行过程。

[原]TCPIP协议卷2之io中断 - 逍遥子 - 逍遥子 曰:

 图2

(1)插口层正在以spl0级别的执行一个中断处理(对应数据A),此时,网络上有新数据过来,接口层产生一个splimp级别的中断,由于splimp优先级高于spl0,因此插口层的执行被打断,接口层的splimp级别的中断处理程序开始执行。

(2)splimp级别的接口层开始进行中断处理(对应数据B),它将完成数据的必要处理,并将数据交给协议层的队列中,并且产生一个splnet级别的中断,此时,接口层继续本层的其他处理直至本层处理完成,因为新产生的splnet中断级别没有当前的中断级别splimp高,因此本层的中断处理不会被打断;

(3)接口层的splimp中断处理完成之后,系统现在还有两个中断要处理:[1]被打断的spl0级别的中断;[2]新产生的splnet中断;由于splnet中断级别高于spl0,因此,先执行splnet中断,在该中断处理过程中将会对接口层传过来的数据进行协议层处理(对应数据B)。

(4)假如协议层的splnet级别中断正在执行过程中,系统又产生了一个spltty级别的中断——终端输入,由于spltty的优先级高于splnet,因此系统就打断splnet级别的中断处理,开始进行spltty的中断处理(对应数据C);

(5)spltty级别的中断程序完成终端输入的处理之后,系统现在还有两个中断要处理:[1]被打断的spl0级别的中断;[2]被打断的splnet级别的中断;由于splnet中断级别高于spl0,因此,系统还是先执行splnet中断完成数据的协议层处理(对应数据B),协议层处理完之后将会为数据B产生一个spl0级别的中断。

(6)splnet将数据处理完成之后,系统还有两个spl0的中断:[1]被打断的spl0中断(对应数据A);[2]新产生的spl0中断(对应数据B),此时,系统将先执行完成被打断的spl0中断,处理数据A;

(7)系统此时还剩下一个新产生的spl0,直接进行该中断的操作,完成数据B的接口层处理。

三、数据同步与互斥

       通过图1可以看到,网络数据需要自底向上经过三个层次才能传递到应用进程,在这三次传递过程中都是通过中断异步来完成,每一层都有自己的进程来完成处理,因此在向上传递过程中保证进程间数据同步是非常重要的。网络数据自底向上传递过程是通过队列完成,每层进程只关心自己需要操作的队列即可,因此数据同步实质上就是对这些分层之间的队列的同步,即自己读队列的时候另一个层级的进程就不要进行插入队列的操作,如下图3所示:当协议层的处理进程正在从队列读取数据时,网络层接口的进程就不能向同一队列中放数据。

[原]TCPIP协议卷2之io中断 - 逍遥子 - 逍遥子 曰:

 

图3

       各层的进程主要通过splnet、splimp与splx配对完成这种同步操作的,在对应上图3中的示例图中,可由下面的代码段1完成操作:

[原]TCPIP协议卷2之io中断 - 逍遥子 - 逍遥子 曰:

 

代码段1

       代码段1是用于协议层与其下面的接口层进行数据共享的操作,其中,ipintrq就是图3中的层间共享数据队列,在协议层执行代码段1时,首先执行splimp,这就屏蔽了下面的接口层产生splimp级别的网络中断,由于接口层的网络中断会频繁发生,因此这里协议层屏蔽接口层的时间不能太长,在代码段1中,只从链表中摘取一个数据节点就立刻取消了屏蔽。

  评论这张
 
阅读(113)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017