资源描述
网络操作系统体系结构,NetworkOperatingSystem,2,2019/12/17,1、对等(PeertoPeer)模式对等式局域网操作系统的特点是网络上的所有连接站点地位平等,因此又称为同类网。,对等网络的规划一般都比较简单,通常采用如图所示的两种结构,2.1体系结构工作模式,3,2019/12/17,2、文件服务器模式文件服务器模式如上图所示,在这种模式中,应用程序和数据都存放在一台指定的计算机中,这台计算机称之为文件服务器,一般均由专业服务器或性能较高的微机担任。文件服务器模式的优点:文件服务器与工作站之间分工明确,使工作站从网络管理中解脱出来,信息处理能力明显增强;数据保密性好,可根据不同需求给用户不同的权限,资源共享性好;文件安全管理较好,可靠性高。,2.1体系结构工作模式,4,2019/12/17,3客户机与服务器客户和服务器都运行于相同的微内核中,让用户和服务器都以用户进程的方式运行,一台机器可以运行单个进程、多个客户、多个服务器或二者的混合。(其主要目的是为了避免面向连接的协议加复杂的报文头)。C/S模式常常以简单的请求/应答协议为基础。,2.1体系结构工作模式,5,2019/12/17,客户机与服务器,2.1体系结构工作模式,6,2019/12/17,客户机与服务器上图的优点“简单”,客户发送一个请求,得到一个应答,在使用前无须建立连接也不用释放连接,应答的消息同时也是对请求的确认。有效性,协议栈比较短,因而也更有效。网络接口层(或OSI中的数据链路层和物理层)处理发送到服务器的数据和返回的数据,这些由硬件完成。,2.1体系结构工作模式,7,2019/12/17,客户机与服务器因此这种简单的结构可以简化为系统通过微内核提供的两个调用:send(dest,&mptr)负责发送报文receive(addr,&mptr)负责接收报文,2.1体系结构工作模式,8,2019/12/17,客户机与服务器Send函数将要发送的消息用指针mptr传给进程,用dest标记目的地,然后阻塞调用者,直到发送完毕为止。receive进程阻塞调用者直到消息被接收为止,当调用结束时将消息拷贝到mptr指向的缓冲区,同时调用这不再被阻塞,addr参数正在监听接收的地址。,2.1体系结构工作模式,9,2019/12/17,客户机和服务器模式的实现寻址。客户为了发送信息给服务器,它必需知道服务器的地址。在Unix系统中采用32位地址指定具体的机器,采用16位的id号来表示本地ID字段,即采用machine.process(机器.进程)的方式。,2.1体系结构工作模式,10,2019/12/17,客户机和服务器模式的实现阻塞和非阻塞原语当一个进程调用send原语,它指定了目的地及发送到该目的地的缓冲区数据。消息传送时,发送的进程被阻塞(挂起)。直到消息传递完毕,其后的指令才能继续执行。同样调用receive时,直到一条消息被实际接收并放入缓冲区时才返回控制权,在一条消息到达前调用receive的进程一直挂起。,2.1体系结构工作模式,11,2019/12/17,客户机和服务器模式的实现阻塞和非阻塞原语在有些系统中,接收者可以指明希望从哪个发送者接收消息,这种情况下它保持阻塞直到该发送者发送的消息到达。和阻塞原语对应的是非阻塞原语(有时候也叫异步原语)。,2.1体系结构工作模式,12,2019/12/17,客户机和服务器模式的实现阻塞和非阻塞原语这种方法的优点是:调用发送进程可以和消息传送并行,而不是让处理器空闲(假设没有其它进程可运行),阻塞原语和非阻塞原语的选择一般取决于系统设计者。,2.1体系结构工作模式,13,2019/12/17,客户机和服务器模式的实现,2.1体系结构工作模式,14,2019/12/17,客户机和服务器模式的实现有缓冲和无缓冲原语像系统设计者可以选择阻塞和非阻塞原语一样,他们也可以选择优缓冲和无缓冲原语,上面描述的基本上是无缓冲原语,意味着一个地址指定给一个特定的进程。如果调用receive(addr,&m),告诉运行的机器内核,调用的进程正在监听地址addr,并且准备接收发送到那个地址的消息。m指出了一个消息缓冲区用于保存传送来的消息。当消息到来,调用接收原语的内核将消息拷贝到缓冲区,并解除该进程的阻塞。,2.1体系结构工作模式,15,2019/12/17,客户机和服务器模式的实现,2.1体系结构工作模式,16,2019/12/17,客户机和服务器模式的实现有缓冲和无缓冲原语只要服务器在服务器在客户机上调用send原语之前调用receive原语,就能运行良好。receive调用只是这样一种机制,它告诉服务器内核服务器正在使用的地址以及存放到来消息的位置,当发送比接收先发上就会产生问题。,2.1体系结构工作模式,17,2019/12/17,2.1体系结构系统内核,内核模块以Linux为例介绍内核及其组件的基本结构,讲述那些重要的内核领域,譬如不同内核的活动形式、存储管理、设备驱动程序、定时器及模块等。主要目标是介绍Linux网络体系结构的运行框架。下列所有领域负责阐明首要网络服务所需要的基本功能。因此,了解这些功能就是理解Linux联网体系结构实现的基本前提。,18,2019/12/17,2.1体系结构系统内核,内核模块下图给出了Linux内核体系结构。Linux内核可以划分为6个不同的部分;每一部分负责处理一项明确的功能,同时又向其它内核组件提供这项功能。这种体系结构反映到内核的源码上这6个部分都形成了各自的子树。,19,2019/12/17,2.1体系结构系统内核,内核模块,20,2019/12/17,2.1体系结构系统内核,内核模块进程管理进程管理部分负责进程及其它内核活动(如软件中断等)的创建和终止。另外,进程间通信(如信号、管道等)也处在这一部分。调度程序是进程管理的主要组件。调度程序负责处理所有的活动进程、等待进程及阻塞进程,它还负责保证所有的应用程序进程都能公平的分享到处理器的计算时间。,21,2019/12/17,2.1体系结构系统内核,内核模块内存管理计算机的存储器是最重要的资源之一。计算机的性能十分依赖于它所配置的内存。另外,内存管理还要负责为每条进程分配各自的存储区,并且保护这些存储区不配其它进程访问。,22,2019/12/17,2.1体系结构系统内核,内核模块文件系统在Linux系统中,文件系统是个中心角色。和其它操作系统(如windowsNT)不同,Linux内核中几乎所有的项目都是以文件系统接口加以处理,例如,设备驱动程序可以表现成一些文件,Proc文件系统则允许访问内核中的数据和参数。,23,2019/12/17,2.1体系结构系统内核,内核模块设备驱动程序设备驱动程序是从各种操作系统中的底层的硬件抽象出来的,从而允许访问这些硬件。尽管Linux是一种整体式内核,但Linux的模块化概念也具备一种运行时添加或删除设备的手段。,24,2019/12/17,2.1体系结构系统内核,内核模块网络子系统由于某些网络操作无法分派给某个特定进程(譬如传入分组处理),因此所有的网络操作都必须交由操作系统处理。传入分组是异步事件。在进程处理它们之间,就必须先收集、标识及转发这些分组。因此,才会由内核负责处理跨程序、跨网络接口的分组。,25,2019/12/17,2.1体系结构系统内核,内核模块在内核中,明确驱动的接口有助于新功能的设计。例如,假设有个接口指向虚拟文件系统,则该接口即可用于添加新的文件系统。Linux可以支持数十种文件系统,这也明确展现了接口确实是Linux开发人员做出的一项优秀设计决策因为还没有其它操作系统能支持如此之多的文件系统。Linux网络体系结构中还包含了很多支持动态添加协议及网络及网络驱动程序接口。,26,2019/12/17,2.1体系结构系统内核,内核中的活动Linux是一种多任务系统。意味着多条应用程序可以同是处于活动状态,也意味着可以同时使用多个应用程序或进程。不过进程并不是Linux系统中唯一可以执行的活动形式。,27,2019/12/17,2.1体系结构系统内核,内核中的活动进程和系统调用进程(process)通常是一些启动已运行的某种特定应用程序的活动,它们会随着应用程序的结束而终止。进程的创建、控制和销毁等任务都由操作系统内核负责处理。进程互斥地运行在处理器的用户地址空间(即出于未保护的模式下);进程从这里只能访问分配给自己的存储区。,28,2019/12/17,2.1体系结构系统内核,内核中的活动进程和系统调用尝试访问其它进程的存储区或内核地址空间都会带来异常,该异常必须由内核进行处理。不过进程如果希望访问设备或使用操作系统内核的某项功能,则必须利用系统调用来做得到这一点。系统调用会让处理器变为受保护模式,而对内核地址空间的访问则是系统调用的一项功能。在受保护模式下可以访问所有设备及存储区,但只有时用内核方法才能做到这一点。,29,2019/12/17,2.1体系结构系统内核,内核中的活动进程和系统调用进程和系统调用的工作可以被其它活动打断。这时它们当前的状态会保存下来;如果这个被中断的进程或系统调用重新工作起来,则会恢复那些被保存下来的状态。,30,2019/12/17,2.1体系结构系统内核,内核中的活动进程和系统调用进程和系统调用可以自愿停止,也可以是非自愿停止。前一种情况下它们会自愿放弃处理例如,进城和系统调用等待某项系统资源(外部设备)而出于睡眠状态,直至得到这项资源为止。非自愿放弃处理是由中断造成的,中断告诉内核一项重要行动一项内河必须处理活动,中断可以是一种关于早期繁忙资源重新可用的通知。,31,2019/12/17,2.1体系结构系统内核,内核中的活动除了正常进程和系统调用的进程外,我们还要区分Linux内核中的其它活动形式。这些活动形式对Linux网络体系结构的重要向具有决定的意义因为网络功能正是在内核中进行处理的。这些活动形式包括:,32,2019/12/17,2.1体系结构系统内核,内核中的活动中断(硬中断)外设利用硬件中断(hardwareinterrupt,HWIRQ)向操作系统通知一些重要的事件(如鼠标移动、键盘按下等)硬件中断打断了处理器正在处理的当前活动,然后去执行相关的中断处理例程。,33,2019/12/17,2.1体系结构系统内核,内核中的活动中断(硬中断)request_irq()函数可以在运行时注册特定的中断处理例程。free_irq()可以用于释放中断的处理例程,这样就不会再执行它。,34,2019/12/17,2.1体系结构系统内核,内核中的活动中断(硬中断)Linux内核中需要区分两种中断:一种是快速中断,它的特征是拥有非常小的中断处理例程,只会很短暂的打断当前的活动,并且在执行期间锁定本地CPU的所有其它中断,在该中断例程执行的过程中是不可以被打断。另一种是慢速中断,在执行的过程中可以被打断,中断处理例程一般较长,因此它们占用处理器的时间一般也较长。,35,2019/12/17,2.1体系结构系统内核,内核中的活动软件中断(softwareinterrupt,softIRQ)实际上是一种不同于真正的中断的、调度后才执行的活动。硬件中断和软件中的主要差别在于,硬件中断会主动打断另一种活动;触发硬件中断会导致打断正在运行的活动。相反软件中断要由一种内核活动来调度它的执行,并不会打断当前正在运行的活动。在Linux系统中定义了32种软件中断。,36,2019/12/17,2.1体系结构系统内核,内核中的活动任务蕾(tasklet)是可以并行可执行的软件中断和旧下半区的一种混和体。,37,2019/12/17,2.1体系结构系统内核,内核中的活动下半区(bottomhalf)一旦出发中断会执行中断处理例程,从而短暂地打断了当前的活动。但并非所有的任务都只用几条语句就可以完成的。例如,若要处理网络适配器收到的分组,则需要数千个时钟嘀嗒标记,然后才能将这个分组传递给用户地址空间的相关进程。,38,2019/12/17,2.1体系结构系统内核,内核中的活动下半区(bottomhalf)尽管中断出发了这项任务,但该任务并非在中断处理例程中执行的。为了保持中断处理的尽可能的小,这种耗时的任务被划分成了两个部分:上半区(tophalf)下半区(bottomhalf)。,39,2019/12/17,2.1体系结构系统内核,内核中的活动下半区(bottomhalf)上半区负责在出发中断之后单纯地运行那些重要的任务,上半区对应着中断处理例程。例如:网络适配器的中断处理例程只负责将接收到的分组复制到内核中,在内核中该分组会被缓存在一个挂起的队列中,其详细的处理由对应的协议实体负责。,40,2019/12/17,2.1体系结构系统内核,内核中的活动下半区(bottomhalf)下半区运行着所有不太紧急的运算及因时间原因而无法在中断处理例程中执行的运算。运行上半区的同时会调度下半区的执行,一旦中断结束而再次调用调度程序,则很可能会运行下半区。,41,2019/12/17,五、操作系统的体系结构,Windows2000的系统结构,42,2019/12/17,2.1体系结构UNIX体系结构,UNIXSystemV系统核心框图,43,2019/12/17,2.1体系结构常用的网络操作系统,具有代表性的网络操作系统有:Microsoft公司的WindowsNTServer、Windows2000Server和WindowsServer2003UNIXUNIX派生的自由软件LinuxNovell公司的Netware,44,2019/12/17,2.1体系结构常用的网络操作系统,1.Windows2000Windows2000有四个版本:Professional、Server、AdvancedServer和DatacenterServer。2.WINDOWS2003它包括StandardEdition(标准版)、EnterpriseEdition(企业版)、DatacenterEdition(数据中心版)、WebEdition(网络版)四个版本,每个版本均有32位和64位两种编码。,45,2019/12/17,2.1体系结构常用的网络操作系统,46,2019/12/17,2.2网络子系统,Linux操作系统的最大特性之一就是它的网络栈。它最初源于BSD((BerkeleySoftwareDistribution,伯克利软件套件)的网络栈,具有一套非常干净的接口,组织得非常好。接口范围从协议无关层(例如通用socket层接口或设备层)到各种网络协议的具体层。Linux中基本网络栈的介绍分为四层的Internet模型,47,2019/12/17,2.2网络子系统,48,2019/12/17,2.2网络子系统,这个栈的最底部是链路层。链路层是指提供对物理层访问的设备驱动程序,这可以是各种介质,例如串口链路或以太网设备。链路层上面是网络层,它负责将报文定向到目标位置。再上一层称为传输层,负责端到端的通信(例如,在一台主机内部)。尽管网络层负责管理主机之间的通信,但是传输层需要负责管理主机内部各端之间的通信。最后一层是应用层,它通常是一个语义层,能够理解要传输的数据。例如,超文本传输协议(HTTP)就负责传输服务器和客户机之间对Web内容的请求与响应。,49,2019/12/17,2.2网络子系统,网络栈的各个层次有一些更为人所熟知的名字。1、在链路层上,可以找到以太网,这是最常用的一种高速介质。更早的链路层协议包括一些串口协议,例如:SLIP(SerialLineInternetProtocol)CSLIP(CompressedSLIP)PPP(Point-to-PointProtocol)。,50,2019/12/17,2.2网络子系统,2、最常见的网络层协议是IP(InternetProtocol),但是网络层中还存在一些满足其他需求的协议,例如ICMP(InternetControlMessageProtocol)ARP(AddressResolutionProtocol),51,2019/12/17,2.2网络子系统,3、在传输层上是TCP(TransmissionControlProtocol)和UDP(UserDatagramProtocol)。4、最后,应用层中包含很多大家都非常熟悉的协议,包括标准的Web协议HTTP和电子邮件协议SMTP(SimpleMailTransferProtocol)等Linux网络栈的架构以及如何实现这种Internet模型。?,52,2019/12/17,2.2网络子系统,53,2019/12/17,2.2网络子系统,最上面是用户空间层,或称为应用层,其中定义了网络栈的用户。底部是物理设备,提供了对网络的连接能力。中间是内核空间,即网络子系统。流经网络栈内部的是socket缓冲区sk_buffs),它负责在源和汇点之间传递报文数据。,54,2019/12/17,2.2网络子系统,系统调用接口系统调用接口可以从两个角度进行描述。用户发起网络调用时,通过系统调用接口进入内核的过程应该是多路的。最后调用./net/socket.c中的sys_socketcall结束该过程,然后进一步将调用分路发送到指定目标。系统调用接口的另一种描述是使用普通文件操作作为网络I/O。,55,2019/12/17,2.2网络子系统,系统调用接口例如,典型的读写操作可以在网络socket上执行(socket使用一个文件描述符表示,与一个普通文件一样)。因此,尽管有很多操作是网络专用的(使用socket调用创建一个socket,使用connect调用连接一个收信方,等等),但是也有一些标准的文件操作可以应用于网络对象,就像操作普通文件一样。最后,系统调用接口提供了在用户空间应用程序和内核之间转移控制的方法。,56,2019/12/17,2.2网络子系统,协议无关接口socket层是一个协议无关接口,它提供了一组通用函数来支持各种不同协议。socket层不但可以支持典型的TCP和UDP协议,而且还可以支持IP、以太网和其他传输协议,例如SCTP(StreamControlTransferProtocol)。通过网络栈进行的通信都需要对socket进行操作。Linux中的socket结构是structsock,这个结构是在linux/include/net/sock.h中定义的。这个巨大的结构中包含了特定socket所需要的所有状态信息,其中包括socket所使用的特定协议和在socket上可以执行的一些操作。,57,2019/12/17,2.2网络子系统,协议无关接口网络子系统可以通过一个定义了自己功能的特殊结构来了解可用协议。每个协议都维护了一个名为proto的结构(可以在linux/include/net/sock.h中找到)。这个结构定义了可以在从socket层到传输层中执行特定的socket操作(例如,如何创建一个socket,如何使用socket建立一个连接,如何关闭一个socket等)。,58,2019/12/17,2.2网络子系统,网络协议对一些可用的特定网络协议作出了定义(例如TCP、UDP等)。它们都是在linux/net/ipv4/af_inet.c文件中一个名为inet_init的函数中进行初始化的(因为TCP和UDP都是inet簇协议的一部分)。inet_init函数使用proto_register函数来注册每个内嵌协议。这个函数是在linux/net/core/sock.c中定义的,除了可以将这个协议添加到活动协议列表中之外,如果需要,该函数还可以选择分配一到多个slab缓存。,59,2019/12/17,2.2网络子系统,网络协议通过linux/net/ipv4/目录中udp.c和raw.c文件中的proto接口,可以了解各个协议是如何标识自己的。这些协议接口每个都按照类型和协议映射到inetsw_array,该数组将内嵌协议与操作映射到一起。inetsw_array结构及其关系如图所示。最初,会调用inet_init中的inet_register_protosw将这个数组中的每个协议都初始化为inetsw。函数inet_init也会对各个inet模块进行初始化,例如ARP、ICMP和IP模块,以及TCP和UDP模块。,60,2019/12/17,2.2网络子系统,网络协议,61,2019/12/17,2.2网络子系统,网络协议proto结构定义了传输特有的方法,而proto_ops结构则定义了通用的socket方法。可以通过调用inet_register_protosw将其他协议加入到inetsw协议中。例如,SCTP就是通过调用linux/net/sctp/protocol.c中的sctp_init加入其中的。socket中的数据移动是使用一个所谓的socket缓冲区(sk_buff)的核心结构实现的。sk_buff中包含了报文数据,以及涉及协议栈中多个层次的状态数据。所发送或接收的每个报文都是使用一个sk_buff表示的。sk_buff结构是在linux/include/linux/skbuff.h中定义的,62,2019/12/17,2.2网络子系统,网络协议,63,2019/12/17,2.2网络子系统,网络协议多个sk_buff可以针对某个给定连接链接在一起。每个sk_buff都在设备结构(net_device)中标识报文发送的目的地,或者接收报文的来源地。由于每个报文都是使用一个sk_buff表示的,因此报文头都可以通过一组指针(th、iph和mac用于MediaAccessControl或者MAC头)方便地进行定位。由于sk_buff是socket数据管理的中心,因此创建了很多支持函数来对它们进行管理。其中有些函数用于创建和销毁sk_buff结构,或对它进行克隆或排队管理。针对给定的socket,Socket缓冲区可以链接在一起,这样可以包含众多信息,包括到协议头的链接、时间戳(报文是何时发送或接收的),以及与这个报文相关的设备。,64,2019/12/17,2.2网络子系统,设备无关接口这一层提供了一组通用函数供底层网络设备驱动程序使用,让它们可以对高层协议栈进行操作。首先,设备驱动程序可能会通过调用register_netdevice或unregister_netdevice在内核中进行注册或注销。调用者首先填写net_device结构,然后传递这个结构进行注册。内核调用它的init函数(如果定义了这种函数),然后执行一组健全性检查,并创建一个sysfs条目,然后将新设备添加到设备列表中(内核中的活动设备链表)。在linux/include/linux/netdevice.h中可以找到这个net_device结构。这些函数都是在linux/net/core/dev.c中实现的。,65,2019/12/17,2.2网络子系统,设备驱动程序网络栈底部是负责管理物理网络设备的设备驱动程序。例如,包串口使用的SLIP驱动程序以及以太网设备使用的以太网驱动程序都是这一层的设备。在进行初始化时,设备驱动程序会分配一个net_device结构,然后使用必须的程序对其进行初始化。这些程序中有一个是dev-hard_start_xmit,它定义了上层应该如何对sk_buff排队进行传输。这个程序的参数为sk_buff。,66,2019/12/17,2.2网络子系统,设备驱动程序设备驱动程序在dev结构中配置好自己的接口之后,调用register_netdevice便可以使用该配置。在linux/drivers/net中可以找出网络设备专用的驱动程序。,67,2019/12/17,2.3网络通信协议,ISO/OSI参考模型,68,2019/12/17,2.3网络通信协议,ISO/OSI参考模型,69,2019/12/17,2.3网络通信协议,链路层面向比特的链路控制规程HDLC各字段的意义,数据链路层的数据传送是以帧为单位的。一个帧的结构具有固定的格式,如图所示。,70,2019/12/17,2.3网络通信协议,链路层面向比特的链路控制规程HDLC分组和桢。分组是把要传输的信息划分为多个子数据段,然后分别传输,每个子数据段称为一个分组。桢是指分组在具体网络上的实现,一个网络上的数据桢是该网络传输数据的最小单元,因此桢只能用于表示数据链路层的分组,因为这一层传输的才是数据的最小单元(其它各层都会加上额外部分,而到了物理层不会再加)。,71,2019/12/17,2.3网络通信协议,链路层面向比特的链路控制规程HDLCHDLC采用零比特填充法使一帧中两个F字段之间不会出现6个连续1。零比特填充的具体做法是:在发送端,当一串比特流数据尚未加上标志字段时,先用硬件扫描整个帧(用软件也能实现,但要慢些)。只要发现有5个连续1,则立即填入一个0。因此经过这种零比特填充后的数据,就可以保证在数据中不会出现6个连续1。在接收一个帧时,先找到F字段以确定一个HDLC帧的边界。接着再用硬件对其中的比特流进行扫描。每当发现5个连续1时,就将这5个连续1后的一个0删除,以还原成原来的比特流,如图所示。,72,2019/12/17,2.3网络通信协议,链路层面向比特的链路控制规程HDLC,73,2019/12/17,2.3网络通信协议,链路层面向比特的链路控制规程HDLCHDLC帧划分为三大类,即信息帧、监督帧和无编号帧,其简称分别是I(Information)、S(Supervisory)和U(Unnumbered)。下图是对应于这3种帧的控制字段以及控制字段中的各比特的作用。,74,2019/12/17,2.3网络通信协议,链路层面向比特的链路控制规程HDLC,75,2019/12/17,2.3网络通信协议,TCP/IP体系结构,76,2019/12/17,2.3网络通信协议,UDP协议,77,2019/12/17,2.3网络通信协议,UDP协议用户数据报的格式用户数据报UDP有两个字段:数据字段和首部字段。首部字段很简单,只有8个字节,如下图所示,由4个字段组成,每个字段都是两个字节。各字段意义如下所述。源端口字段:源端口号。目的端口字段:目的端口号。长度字段:UDP用户数据报的长度。检验和字段:防止UDP用户数据报在传输中出错。,78,2019/12/17,2.3网络通信协议,UDP协议用户数据报的格式注意:UDP数据报中计算校验和方法有点特殊,在计算校验和时在UDP数据报前加12字节的伪首部,伪首部并不是真正的首部,只是在计算校验和时得到的一个临时的过渡的数据报。伪首部既不向下传递以不向上提交。,79,2019/12/17,2.3网络通信协议,UDP协议,80,2019/12/17,2.3网络通信协议,TCP协议传输控制协议TCPTCP是TCP/IP体系中面向连接的运输层协议,它提供全双工的可靠交付的服务。一个TCP报文段分为首部和数据两部分,如下图所示。TCP报文段首部的前20个字节是固定的,后面有4N字节是根据需要而增加的选项(N必须是整数)。因此TCP首部的最小长度是20字节。,81,2019/12/17,2.3网络通信协议,TCP协议,82,2019/12/17,2.3网络通信协议,TCP协议传输控制协议TCP首部固定部分各字段的意义如下所述。源端口和目的端口,各占两字节。序号,4字节。TCP是面向数据流的,在传送的数据流中,每一字节都有一个序。例如,一报文段序号为200,而其数据共100字节,那么下一报文段序号就为300。确认序号,4字节,期望收到的下一报文的数据的第一个字节的序号。也就是下一报文段首部序号。序号长度4GB可以保证序号重复时,旧序号早已在网络中消失了。,83,2019/12/17,2.3网络通信协议,TCP协议首部固定部分各字段的意义如下所述数据偏移,指出数据开始处距离TCP报文段的起始处多远。实际上也就是TCP报文段首部的长度。偏移单位是32位字。保留,暂时不用。留作后用。紧急比特URG(URGent),当URG为1时表示此TCP应当尽快传递(高优先级),而不是按原先排队传递。确认比特ACK,只有当ACK=1时确认号字段才有意义,ACK=0确认号字段没意义。,84,2019/12/17,2.3网络通信协议,TCP协议首部固定部分各字段的意义如下所述推送比特PSH(PuSH),当PSH为1时表明请求立即将本数据报传送给应用层,而不是等缓存都填满后再传送。复位比特RST(ReSeT),当RST=1时表明严重差错,必须立刻释放连接,然后再重新连接。同步比特SYN,连接建立时使用,当SYN=1,而ACK=0表明是一个连接请求报文段,如果对方同意建立连接则发送SYN=1,ACK=1。,85,2019/12/17,2.3网络通信协议,TCP协议首部固定部分各字段的意义如下所述终止比特FIN(FINal),用来释放连接,当FIN=1,表明欲发送的字符已经发完,并请求断开连接。窗口,该窗口告诉对方在未收到确认的情况下,能发送的字节数之多是此窗口大小。检验和,计算和UDP类似。选项,长度可变,即最大TCP报文长度。MSS(maximumsegementsize),告诉对方我的缓存最多能够接收的报文段最大长度为MSS字节。当没有选项时,TCP首部长度为20字节。,86,2019/12/17,2.3网络通信协议,TCP协议,87,2019/12/17,2.3网络通信协议,TCP协议TCP的运输连接管理。TCP是面向连接的协议。运输连接的建立和释放是每一次面向连接的通信中必不可少的过程。在连接建立过程中要解决以下三个问题。要使每一方能够确知对方的存在。要允许双方协商一些参数(如最大报文段长度,最大窗口大小,服务质量等)。能够运输实体资源(如缓存大小,连接表中的项目等)进行分配。,88,2019/12/17,2.3网络通信协议,TCP协议TCP的连接和建立都是采用客户服务器方式。主动发起连接建立的进程叫做客户(client),而被动等待连接建立的进程叫做服务器(server)。,89,2019/12/17,2.3网络通信协议,TCP协议,90,2019/12/17,2.4TCP/IP体系与网络互联,IP数据报格式,91,2019/12/17,2.4TCP/IP体系与网络互联,IP数据报格式IP数据报的格式能够说明IP协议具有什么样的功能。从图中可以看出一个IP数据报由首部和数据两个部分组成。首部的前一部分是长度固定的20字节,后一部分则是长度可变的。其各自段的含义如下:版本,占4bit,指明IP协议的版本,通信双方使用的IP协议版本要一致,目前的IP协议版本是4(IPVersion4)。以前的三个版本目前已经不再是使用了。,92,2019/12/17,2.4TCP/IP体系与网络互联,IP数据报格式首部长度,占4bit,可表示的最大数值为15个单位(一个单位为4字节)。因此IP数据报的首部最大长度可以为60字节。当IP分组首部长度不是4字节的整数倍时,必须理由最后一个填充字段进行填充。因此数据部分永远在4N(N=5,6,7)时开始,这样实现起来较为方便。,93,2019/12/17,2.4TCP/IP体系与网络互联,IP数据报格式服务类型,占8bit,用来获得更好的服务。服务类型的前3bit表示优先级,它可以使数据报具有8个优先级中的一个。第4bit为Dbit表示要求有更低的时延。第5bit为Tbit要求有更高的吞吐量。第6bit为Rbit表示要求有更高的可靠性,即在数据报传输的过程中被节点交换机丢弃的可能性尽可能的小。第7bit为Cbit是新增加的,是要求选择费用更低廉的路由。最后1bit目前尚未使用。在相当长的时间内服务类型(TypeofService)字段并没有引起很多人的重视。直到最近几年,当需要将实时媒体在因特网上传输时,服务类型字段才引起大家的重视。,94,2019/12/17,2.4TCP/IP体系与网络互联,IP数据报格式总长度,表示首部和数据部分的长度和,单位为字节。总长度字段占16bit,因此数据报的最大长度为216-1(65535)字节,然而实际应用中却很少有长度超过1500字节的数据报。当有很长的数据报需要传送时,总长度是指分割受的数据报长度,而不是指未分片前的总长度。标识,主要作用是使分片后的数据报在接收端能够被准确的重新组装成原先的数据报。注意:标识没有顺序的号的意思,因为IP数据报时无连接的服务,数据报不存在按序接收的问题。,95,2019/12/17,2.4TCP/IP体系与网络互联,IP数据报格式标志,占3bit,目前只有前2bit有意义。低位为MF(MoreFragment)。MF=1表示后面还有分片的数据报,MF=0表示这是若干数据报分片中的最后一个。中间的一位为DF(DontFragment),意思为不能分片,只有当DF=0时才允许分片。片偏移,指出较长的分组在分片后,某片在原分组中的相对偏移位置。也就是说,相对于用户数据字段的起点,该片从何处开始,片偏移以8字节为偏移单位。,96,2019/12/17,2.4TCP/IP体系与网络互联,IP数据报格式寿命,即TTL,即数据报在网络中的生存时间,其单位为s,寿命的建议值为32s,但也可以设置为34s,甚至255s。协议,占8bit,协议字段指出此数据报携带传输层数据使用的是什么协议,以便目的主机的IP层指导将此IP数据报上交给那个进程。常见的协议和相应的协议字段值为:UDP(17),TCP(6)等。,97,2019/12/17,2.4TCP/IP体系与网络互联,IP数据报格式首部校验和,此字段只检验数据包的首部,不包括数据部分。因为数据报每经过一个节点,节点处理机就会计算一次首部校验和(一些字段如寿命、标志等可能发生变化)如果连数据部分一起计算那么计算量就太大了。地址,首部中最为重要的字段。源IP地址和目标IP地址字段各占4字节。,98,2019/12/17,2.4TCP/IP体系与网络互联,IP数据报格式可变部分字段,IP数据报的可变部分字段就是一个选项字段。选项字段用来支持排错、安全等措施,内容丰富。此字段长度可变,从1字节到40字节不等,取决于所选择的项目。但这个字段较少时用。,99,2019/12/17,2.4TCP/IP体系与网络互联,数据报的实现操作系统网络子系统最重要的任务之一就是根据使用的协议处理数据报文。在系统设计上,除了考虑到这些协议的性能和正确性外,协议实现的多样性和灵活性也扮演着重要的角色。,100,2019/12/17,2.4TCP/IP体系与网络互联,数据报的实现许多网络协议表面上看有很大差异,但是,当操作系统内部进行实现时,很快就会发现在数据报文上的算法和操作是类似的,并且它们大多可以被复用。这里以Linux为例来说明数据报文具体是如何实现的,以及有哪些常用的处理方法。,101,2019/12/17,2.4TCP/IP体系与网络互联,数据报的实现Linux网络实现的灵活性和高效性的一个主要因素是缓冲体系结构,它管理了网络报文所谓套接字缓存(socketbuffer),或简称sk_buff。这种网络实现方式的核心结构代表了报文在整个内核中的整个处理过程和生命周期。,102,2019/12/17,2.4TCP/IP体系与网络互联,数据报的实现这里介绍套接字缓存结构,以及用来管理它们的操作,从介绍socketbuffer结构开始,说明IP报文在此结构中是如何表示的,以及在穿越不同的协议和层的过程中他是如何发生变化的,以及用来管理和更改此结构的常用函数。,103,2019/12/17,2.4TCP/IP体系与网络互联,数据报的实现Linux的网络实现方式是独立于某个具体协议的,可以同时运用于网络层、传输层和网络接口层的协议。套接字缓存是用来表示和管理Linux内核中报文的数据结构。如下图所示。,104,2019/12/17,2.4TCP/IP体系与网络互联,数据报的实现,105,2019/12/17,2.4TCP/IP体系与网络互联,数据报的实现一个套接字缓存由两部分组成:数据报文:该存储区域保存了实际网络中传输的数据。即协议数据单元。管理数据(sk_buff):当一个数据报文在Linux内核中进行处理时,内核需要额外的数据,这数据没有必要存储在实际的报文中。这些特有的数据包括指针、计时器等。它们是协议实例间交换的接口控制信息(InterfaceControlInformation,ICI)的重要部分(还有函数调用时传递的参数)。,106,2019/12/17,2.4TCP/IP体系与网络互联,数据报的实现next,prev用于链接队列中套接字缓存。它们应当总是由可以处理套接字缓存的特定函数来处理,不应当被程序员直接修改。list用于指向套接字缓存在队列中的当前位置。出于这个原因队列应当总是structsk_buff_head类型的,这样那个它们才可以被套接缓存的操作所管理。对于没有被分配到任何队列的报文,此指针应当指向null。,107,2019/12/17,2.4TCP/IP体系与网络互联,数据报的实现sk指向创建报文的socket。网络适配器的驱动程序会为软件路由器创建套接字缓存结构。这意味着保温并没有分配到一个有效的socket上,所以指针指向null。stamp表示报文到达Linux的时间(瞬时)。,108,2019/12/17,2.4TCP/IP体系与网络互联,数据报的实现dev和rx_dev是网络设备的引用,dev表明套接字缓存当前操作所在的网络设备。一旦路由器选择被确定下来,dev就指向报文离开计算机时经由的网络适配器。直到报文的输出适配器确定之前,dev都指向输入适配器。rx_dev总是指向接收报文的网络适配器。,109,2019/12/17,2.4TCP/IP体系与网络互联,数据报的实现h,nh和mac分别表示指向传输层(h)、网络层(nh)和网络接口层(mac)的报文头指针,这些指针针对报文设定,就像闯过了内核。例如:IP报文的h指针在函数ip_rcv中被设定为指向IP协议头(typeiphdr)。,110,2019/12/17,2.4TCP/IP体系与网络互联,数据报的实现dst指向路由高速缓存中的一条记录,这说明它包含着有关报文进一步进一步前进的信息(例如,报文通过哪个适配器离开计算机)或包含着存储在硬件桢头高速缓存中的一个MAC头引用。,111,2019/12/17,2.4TCP/IP体系与网络互联,数据报的实现skt_type表示一个报文的类型,可以是如下类型中的一个:PACKET_HOST表示一个发送到本机的报文。PACKET_BROADCAST表示一个广播报文。PACKET_MULTICAST表示一个多播报文。PACKET_OTHERHOST表示非到本机但在特定模式下被接收的报文。PACKET_OUTGOING表示离开计算机的报文。PACKET_LOOPBACK表示从本机发送给自己的报文。PACKET_FASTROUTE表示在特定网卡间快速转发的报文。,112,2019/12/17,2.4TCP/IP体系与网络互联,数据报的实现len指明套接字缓存所表示的报文长度,这里只考虑内核可访问的数据。这意味着在网络接口层中只有两个mac地址和类型/长度域被考虑在内。其它域(报文头、链接和校验和)以后在网络适配器中添加,这也是为什么它们没有被内核处理的原因。,113,2019/12/17,2.4TCP/IP体系与网络互联,数据报的实现data、head、tail、end:data和tail指针指向当前的有效报文数据。依赖于当前处理报文的层,这些参数表明了当前的有效协议数据单元。head和end指向可以用于报文数据的整个单元。位于head和data之间的空间称为headroom,位于tail和end之间的空间称为tailroom。,114,2019/12/17,2.4TCP/IP体系与网络互联,数据报的实现其它参数这里不作讨论,因为它们的重要性较低。datarefp实际上并不是skb_buff结构的一部分,因为它们位于报文数据区的末尾并且不是被定义为结构的一个变量。datarefp是一个引用计数器,它们可以通过skb_datarefp(skb)宏很容易被定为和操作。,115,2019/12/17,2.4TCP/IP体系与网络互联,数据报的实现套接字缓存是用来定位和管理一个报文在内核中被处理的整个周期。当应用程序向一个socket传输数据后,该socket就创建相应的套接字缓存并将有效的数据地址存入此结构变量中。在报文穿过各层的过程中,每一层报文头信息被插入到有效数据之前。,116,2019/12/17,2.4TCP/IP体系与网络互联,数据报的实现由于报文头部有足够的空间,避免了报文头之后都有效数据的多次拷贝(相对于其它操作系统而言)。有效数据只被拷贝两次:一次是当他从用户地址空间被传输到内核地址空间时。第二次是当报文数据被传送到网络适配器上的时候。在Linux中位于当前合法报文数据之前的自由存储空间称为headroom位于当前报文数据之后的存储空间称为tailroom。,117,2019/12/17,2.4TCP/IP体系与网络互联,数据报的实现,118,2019/12/17,2.4TCP/IP体系与网络互联,IPv6数据报格式,119,2019/12/17,2.4TCP/IP体系与网络互联,IPv6数据报格式,120,2019/12/17,2.4TCP/IP体系与网络互联,IPv6数据报格式每个IPv6数据报都从基本首部开始,如图7-33所示。在基本首部后面是有效载荷,它包括高层的数据和可能选用的扩展首部。下面是IPv6基本首部中的各字段。版本(version),4bit。指明协议版本,对于IPv6该字段为6。,121,2019/12/17,2.4TCP/IP体系与网络互联,IPv6数据报格式优先级(trafficclass),4bit。使源站哪够指明数据报的流类型。首先,IPv6将流分为两类,即可以进行拥塞控制和不可以进行拥塞控制的,每一类又可以分为8个优先级,优先级值越大表明该分组越重要,优先级仅在类别之内有意义。对于可进行用塞控制的业务其优先级为07,对于不可以进行拥塞控制的业务其优先级为815。,122,2019/12/17,2.4TCP/IP体系与网络互联,IPv6数据报格式优先级0:应用层未指明数据报优先级。1:如USENET报文。2:如电子邮件。4:用于打块数据传送,如FTP或HTTP。6:用于交互性业务,如TELNET。优先级3和7保留今后使用。8:丢弃数据报产生的影响最小,如高保真度视像(由于这种信号有相当多的冗余度,丢失少量数据报也不会被察觉)15:丢弃数据报产生的影响较大,如低保真度视像。,123,2019/12/17,2.4TCP/IP体系与网络互联,IPv6数据报格式流标号(flowlabel),24bit,IPv6的一个新的机制支持资源预定,并且允许路由器将每个数据报与一个给定的资源分配相联系。IPv6提出流的抽象概念。所谓流就是互联网上从一个特定源站点到一个特定目的站的一系列数据报,而源站要求在数据报传输的路径上的路由器保证指明的服务质量。例如:两个要发送视频的应用程序可以建立一个流,它们所需要的带宽和时延再此流觞可以得到保证。,124,2019/12/17,2.4TCP/IP体系与网络互联,IPv6数据报格式有效载荷长度(payloadlength),16bit,指明除首部长度外,IPv6数据报所载字节数。(即扩展首部和数据部分的净长度)下一个首部(nextheader),8bit,标识紧接着IPv6首部扩展首部的类。这个字段指明在基本首部后面紧跟着的一个首部类型。,125,2019/12/17,2.4TCP/IP体系与网络互联,IPv6数据报格式跳数限制(hoplimit),8bit,此字段用来防止数据报在网络中无限期地存在。源地址,128bit。目的地址,128bit。,126,2019/12/17,2.5协议的实现,分析LINUX网络协议栈中SKBUFF的实现。分析以LINUX2.2.x为基础,同时也包括了相同的描述对象在LINUX2.4.x中的新变化。本文引用的代码的版本分别是LINUX2.2.25,LINUX2.4.20。,127,2019/12/17,2.5协议的实现,sk_buff结构是linux网络子系统中最重要的数据结构,它表示接收或发送数据包的包头信息。包含很多成员变量供网络代码中的各子系统使用。了解sk_buff的数据组成,以及相关的重要函数。,128,2019/12/17,2.5协议的实现,网络协议栈是一个有层次的软件结构,层与层之间通过预定的接口传递网络报文。网络报文中包含了在协议栈各层使用到的各种信息。网络报文的长度是不固定的,因此采用什么样的数据结构来存储这些网络报文就显得非常重要。在BSD的实现中,采用的数据结构是mbuf。LINUX的实现中采用sk_buff。,129,2019/12/17,2.5协议的实现,sk_buff的定义,130,2019/12/17,2.5协议的实现,sk_buff的定义,131,2019/12/17,2.5协议的实现,sk_buff的定义,132,2019/12/17,2.5协议的实现,sk_buff的定义,133,2019/12/17,2.5协议的实现,sk_buff的定义,134,2019/12/17,2.5协议的实现,sk_buff的定义数据报文的存储空间是在网络设备收到网络报文或者应用程序发送数据时分配的,分配的空间以16字节为一个单元。分配成功之后,将网络报文填充到这个存储空间中去。数据报文在存储空间里的存放的顺序依次是:链路层的头部,网络层的头部,传输层的头部,传输层的数据。,135,2019/12/17,2.5协议的实现,sk_buff的定义sk_buff和网络报文之间的关系如图所示,136,2019/12/17,2.5协议的实现,与sk_buff相关的函数与sk_buff相关的函数涉及到网络报文存储结构和控制结构的分配、复制、释放。控制结构里的各指针的操作。各种标志的检查。,137,2019/12/17,2.5协议的实现,与sk_buff相关的函数函数:structsk_buff*alloc_skb(unsignedintsize,intgfp_mask)说明:分配大小为size的存储空间存放网络报文,同时分配它的控制结构。,138,2019/12/17,2.5协议的实现,与sk_buff相关的函数函数:structsk_buff*skb_clone(structsk_buff*skb,intgfp_mask)说明:从控制结构skb中clone出一个新的控制结构,它们都指向同一个网络报文。同时还增加网络报文的引用计数(这个引用计数存放在存储空间的结束地址的内存中,由函数atomic_t*skb_datarefp(structsk_buff*skb)访问,引用计数记录了这个存储空间有多少个控制结构)。,139,2019/12/17,2.5协议的实现,与sk_buff相关的函数函数:structsk_buff*skb_copy(structsk_buff*skb,intgfp_mask)说明:复制控制结构skb和它所指的存储空间的内容。复制成功之后,新的控制结构和存储空间与原来的控制结构和存储空间相对独立。,140,2019/12/17,2.5协议的实现,与sk_buff相关的函数函数:voidkfree_skb(structsk_buff*skb)说明:释放控制结构skb和它所指的存储空间。,141,2019/12/17,2.5协议的实现,与sk_buff相关的函
展开阅读全文