您的位置:首页 > 理论基础 > 计算机网络

Linux网络内核―学习与思考

2007-11-03 23:39 323 查看
对操作系统的软件体系结构进行抽象,一般认为Linux内核由进程调度(SCHED)、内存管理(MM)、虚拟文件系统(VFS)、进程间通信(IPC)以及网络接口(NET)等五个子系统构成,各个子系统都对其它子系统存在着不同程度的依赖关系,其内在微妙联系与彼此间复杂的通信为整个系统的卓越性能奠定了基础。仅从操作系统的这个一般视角来看,网络子系统已经显示其不可忽视的重要性,网络功能也早已成为现代操作系统的基本目标之一。但实际上Linux一开始便诞生于网络,其不断的壮大与完善本身也是在网络环境中推进,作为一种主流的网络操作系统,它以其强大的网络支撑功能、高级别网络安全性能和持续稳定运行等特性在应用服务器平台市场的占有份额逐年增长,不仅是微软基于NT技术的网络服务器在这一领域最大的强敌,而且就整个应用领域来观察,Linux网络服务器平台一直以来也都是占据着主要的支配位置。
Linux内核的网络部分即其网络内核本身也是按照层次模型来布局的,用户的应用进程与网络内核的直接接口是Socket,具体的网络通信协议工作于Socket下面的协议层,处于最底层的是网络通信的硬件设备。事实上在这每一个层次的内部又存在着多个可以断续细分的诸多层次,网络上传输的数据在到达主机或是将要从主机发送出去之前分别沿着自下而上和由上到下的次序进行传递,不能跨越其中的任何一个层次,内核对这一传输路径的唯一性的保证成为整个网络子系统的可靠性与准确性的前提。
我们知道Linux的内核源码主要是用C语言编写。不过,在网络子系统的设计与实现上,面向对象的设计思想则得到了明显的体现。尽管没有直接引入类的定义,也没有正式的封装继承等明确的OOP概念,但其将数据的属性与操作集合设计在某个集成的数据结构中的思想在本质上还是显示了面向对象的特性,比如网络内核部分最为重要的数据结构device结构和sk_buff结构就是很好的实例。在这种面向对象的设计思路下,网络设备接口、Socket缓冲区、Socket及网络协议被视为这一子系统的核心”网络对象”,而整个网络内核的设计实现也正是围绕着这四个主要对象及其相互间的联系和通信展开的。这四者分别体现着网络子系统与内核的其它子系统间的关系,网络内核的运行离不开VFS、MM以及SCHED的支持,其中的Socket缓冲区对象正是反映了网络子系统与MM的密切关系――Socket缓冲本身就是在虚拟内存中开辟的一块空间,对它的管理实际上很大程序上都是依赖于内存管理子系统提供的功能;而对Socket这一网络对象的管理涉及到信号同步,文件描述行符的分配与访问等内核中SCHED和FS等子系统的功能。

Socket缓冲区

网络通信协议

Socket(套接字)

网络设备接口

网络内核对象及其相互关系

在上述的四个核心的网络对象当中,Socket缓冲区因其与其它三个对象均有着直接的依赖关系而成为最核心的网络对象,事实上Linux的网络内核源码中也的确是在对网络缓冲区的管理上花费了最多的份量。我们可以结合网络中两个端点间一次通信的工作流程来理解这种缓冲区的作用:当发送方有数据要发出而建立其用于发送的Socket后,相应的Socket缓冲区便会在套接层建立起来,然后随着数据从应用进程自上而下向物理层传输,各层协议会在同样向下传递的Socket缓冲区中添加对应的协议头部和尾部(Header&Tail),最后当所要发送的数据在物理层组织成比特流后,Socket缓冲区在此层释放而消失。当数据经由网络通路到达接收端后,所要进行的工作基本上与此相反:Socket缓冲区在物理层建立,并开始沿着自下而上的次序依次传递到接收方的Socekt层,在这个传递的过程中各层协议的头部与尾部在从数据包中移除的同时也会在Socekt缓冲区中被删除掉,最后当数据到达接收方的Socket层后,真正要传递的数据交给接收端的应用进程,Socket缓冲区在套接层消失。这些工作的执行,包括对组织这些网络缓冲区的链表的操作实现,都有赖于Linux网络内核提供的有关于Socket缓冲区分配回收和流程控制的一系列函数接口的调用――这些调用可以在网络设备驱动程序的一些标准例程中找到。
另一个极为关键的结构是device,容易看出它是与四个核心网络对象中的网络设备接口密切相关的,事实上这一结构涉及到一般的设备驱动程序编写的问题。向Linux内核注册一种新的网络设备最主要的工作可以简单地认为是完成这一结构中所定义的内容并将其挂到系统的网络设备表当中去。当然,Linux对模块机制的支持是其重要优点之一,如果网络设备驱动是用模块的形式存在而不是编译到内核本身当中,则还需要做一些与模块的注册、初始化,卸载等相关的工作,这部分内容本身可以说的已经不少了,留到下次讨论吧。但不得不提到的是在这个结构中包括了所有在该网络设备上进行数据的发送与接收从FS的层面所需要的标准操作例程集合,不能忽视的一点是网络设备本身对Linux而言也是当作文件来处理的,我们所熟悉的file结构中file_operations*指针将需要指向这一操作集――网络数据的发送与接收本身也就是对网络设备文件的读写操作。
上面其实已经涉及到了Linux的套接字层次问题,对此我觉得有必要理解的是在我们进行网络应用编程时所熟知的Socket实际上是处于这一层次最上面的BSDSocket层,这一层可以认为是一个统一的抽象套接层,它屏蔽了下面的地址族套接层所牵涉到的不同地址族在寻址方式,通信协议方面的差异。比如我们最为熟悉的TCP/IP对应于INET地址族,这一层次相应地就是INET层。在这个层次模型的最下面是协议层,具体而言也就是上层地址族所包含的一些网络通信协议,如TCP、UDP。网络应用程序中调用的BSDSocket的操作是以地址族在内核中所注册的协议操作集提供支撑为基础的,内核中pops向量各项中的proto_ops结构指针所指向的结构中包含了这些协议操作例程的定义.

///////////////////////////////////////////////////////////////////////////////
以上仅仅是在学习Linux内核中的一些个人理解,相信表述错误肯定会有,很希望能得到大家的指点,也期待能和各位一起讨论学习。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: