目录
协议栈分层思想
1. 网络接口层
2. 网络层
3. 传输层
4. 应用层
进程模型
单进程模型
协议栈编程接口
1、Raw/Callback API
2、Netconn API
3、Socket API
协议栈分层思想
TCP/IP协议完整的包含了一系列构成互联网基础的网络协议,TCP/IP协议的开发出现在OSI之前,因此它并没有按照OSI模型中描述的各种结构来实现,而是有着自己的协议层次划分特点。TCP/IP协议模型可以划分为4个层次,从上到下依次为:网络接口层(Network Interface Layer)、网络层(Internet Layer)、传输层(Transport Layer)和应用层(Application Layer),如图所示,在所有层次结构中,每一层建立在低一层提供的服务上,低一层为高一层提供服务,最终完成数据在两台互联网主机之间的传递。
1. 网络接口层
网络接口层是TCP/IP协议模型的最底层,主要负责网络上数据帧的发送和接收,数据帧是底层网络传输的基本单元。网络接口有不同的实现方式,比如可以通过有线或者无线的方式发送数据帧,不同的实现方式意味着不同的帧结构、发送速率等。网络接口层一方面将上层(网络层)的数据组装成自己特定的数据帧并发送,另一方面接收网络中发送给自己的数据帧,并解析出帧中的数据后递交到上层。
2. 网络层
网络层负责在主机之间的通信中选择数据报的传输路径,即路由。当网络层接收到来自于上层(传输层)的数据分组后,它会把分组封装在IP数据报中,填入数据报的首部,使用路由算法来确定是直接交付数据报还是把它传递给路由器,然后把数据报交给适当的网络接口进行传输。
网络层还要负责处理传入的数据报,并校验其数据有效性,然后判断该数据报是否是给本机的,如果不是,则使用路由算法将数据报出去转发,如果是,网络层需要除去该数据报中的首部得到数据分组,然后将数据分组递交给上层(传输层)。
3. 传输层
传输层主要是提供应用程序之间的通信服务,这种通信又称为端到端通信。传输层协议把上层应用层要传输的数据流划分为分组,把每个分组连同目的地址交给网络层去发送。传输层要系统地管理两端数据的准确交互,要提供可靠的传输服务,以确保数据到达无差错、无乱序。为了达到这个目的,传输层协议可以采用协商、确认、重发等机制。
4. 应用层
应用层是分层模型的最高层,它最简单的解释就是利用传输层提供了数据传输功能发送自己的数据到对方。传输层协议类型有多种,不同的类型意味着不同的传输速度和可靠性,而往往这二者是不可兼得的。所以每个应用程序选择最合适的传输服务类型,以使得双方之间的数据传输达到最佳效果。
上面是一个标准的TCP/IP协议结构,各个层都被描述为一个独立的模块形式,每一层负责完成一个独立的通信问题。例如,网络接口层负责完成IP数据包在物理线路传输时的封装、传递问题;网络层完成数据包选路和路由,负责将数据包从源主机发送到目标主机;传输层完成数据在两台主机间的端到端传递,IP地址只能唯一的标识一台主机,而端口号可以唯一标识出主机上的不同进程,传输层通过识别端口号来向不同的用户应用程序递交数据。TCP/IP的这种分层方式为协议栈的涉及提供了一种很好的解决方案,因为每个层都相互独立,他们都可以被单独实现,只要保证他们的街廓不变就可以了。
但是,上述的实现方案,会导致一个问题就是数据包在各层之间的递交变得非常缓慢,因为它涉及到一系列的内存拷贝问题,因此,系统总体性能会受到影响。为了避免这种现象的发生,LWIP内部并没有采用这种完整的分层结构,它会假设各层间的部分数据结构和实现原理在其他层是可见的。这样数据包在递交过程中,各层协议可以直接对数据包中属于其他层次协议的字段进行操作,这将使整个协议栈对数据包的操作更加灵活。
LWIP实现时,参考了TCP/IP协议的分层思想,即每一层都在一个单独的模块中实现,并为其他层次的模块提供一些输入/输出接口函数。LWIP包含了许多的模块,每个模块都在一个单独的文件中实现,除了实现基本的TCP/IP功能之外,还有许多支持这些基本模块实现的附加模块,例如操作系统模拟层,数据包和内存管理机制,网络结构管理层,数据检验和计算模块及API模块。即使这样,LWIP并没有遵循严格的分层机制,这是因为为例节省时间和内存空间上的开销,各个层次之间可能存在交叉存取的现象。
另一方面,在许多其他TCP/IP协议的实现中,即使内核各层存在着- -定的交错现象, 但 另一方面,在许多其他TCP/IP协议的实现中,即使内核各层存在着--定的交错现象,但在用户应用程序和协议栈内核之间也会保持着很明显的分层结构。在操作系统中,TCP/IP 协 在用户应用程序和协议栈内核之间也会保持着很明显的分层结构.在操作系统中,TCP/IP协议往往被设计为内核代码的一部分,用户可以使用的只是协议为用户提供的几个API函数, 议往往被设计为内核代码的一部分,用户可以使用的只是协议为用户提供的几个api函数,或者操作系统对网络通信函数进行了完全的封装,用户可以像操作简单文件那样来处理网络连 或者操作系统对网络通信函数进行了完全的封装,用户可以像操作简单文件那样来处理网络连接中的数据(例如常见的BSD socket)。也正因如此,应用程序并不知道协议栈内部使用的数 接中的数据(例如常见的BSD套接字)也正因如此,应用程序并不知道协议栈内部使用的数据包结构与机制,它也就不能充分利用协议栈中数据包的组织结构来避免数据的拷贝。在数据 据包结构与机制,它也就不能充分利用协议栈中数据包的组织结构来避免数据的拷贝.在数据包发送时,用户数据必须全部从用户进程区域拷贝到协议栈内部缓冲区。 包发送时,用户数据必须全部从用户进程区域拷贝到协议栈内部缓冲区.
进程模型
协议的进程模型可以理解为协议实现时被划分在几个进程中,即实现具体协议栈时需要几个进程。
单进程模型
即让协议栈中的每个模块都独立地成为一个进程,在这种模式下,各个模块之间有个明显的界限区分。协议栈各个模块能够随着程序的运行而自由添加,只有被使用到的模块才被添加,这使得协议的代码组织更加灵活;此外,这种模块化的结构也使协议栈的代码编写和调试显得更加轻松。但正如前面所述,严格的分层结构并不是实现协议栈的最好方式,最重要的,当数据包在各个层次间递交时,就会涉及到各个进程频繁的问题。例如,对于-一个底层网卡收到的TCP报文段,这意味着必须进行最少三次的进程切换:底层数据包接收进程调用网卡驱动接收数据包;然后进程切换,进入IP层进程处理数据包并将数据报递交给TCP层;此后,系统进入TCP进程处理收到的报文;最后还需进入用户进程处理TCP层递交的数据,在许多操作系统中,进程的切换是- -件开销很大的事情,所以单进程模型会使得协议栈的效率降低。
另一种实现方式是使协议栈驻留在操作系统中,成为操作系统的一部分,这样,用户进
程与协议栈内核之间进行交互就是通过操作系统提供的系统函数来实现的。这种情况下,协议栈内部的各层之间不会有明显的分层界限,可以在各层之间采用一定的交叉编程技术来提高协议栈的执行效率。
LwIP采用了这样- - -种进程模型,即协议栈内核同操作系统内核互相隔离,而同时整个协
议栈作为操作系统中的一个单独进程而存在。用户应用程序可以驻留在协议栈内核的进程中,也可以实现为一一个单独的进程。当采用第一种方式时, 用户程序与协议栈之间的通信是通过回调函数(即前面所说的Raw/Callback API)来实现的;当使用第二种方式时,需要使用协议栈中的操作系统模拟层提供的信号量与邮箱机制,实现用户进程和协议栈内核的数据交互,这时可以用其他两种API进行编程,即Sequential API和Socket API。
将LwIP实现为系统中一个单独的进程,而不是作为系统内核的一部分, 这样做既有优点
也有缺点。最大的优点在于协议栈可以在任何操作系统上进行移植,缺点在于协议栈进程的运行需要操作系统的调度,这使得有时候协议栈响应的实时性会受操作系统调度的影响。因此, 行需要操作系统的调度,这使得有时候协议栈响应的实时性会受操作系统调度的影响.因此,在嵌入式操作系统中使用LwIP时,最好将LwIP进程设置为系统中具有最高优先级的进程, 在嵌入式操作系统中使用LwIP时,最好将LwIP进程设置为系统中具有最高优先级的进程,以提高协议栈的实时性。 以提高协议栈的实时性.
协议栈编程接口
LWIP具有三种协议栈编程接口,分别是RAW/Callback API、Sequential(netconn) API、Socket API.
其中后两者是必须依赖于操作系统中的邮箱、信号量机制来实现的,而RAW/Callback是在有无操作系统下都可以进行的。
网络上建议的都是使用前面二者相结合的方式来进行编程,Socket API的效率比较低,但是编程较为简单。
1、Raw/Callback API
Raw/Callback API 是一种最直接的方法利用协议栈,应用程序通过函数注册的方式与内核产生联系,效率较高,另一方面,我们从编程模式上来看看原始/回调API的弊端,由于用户应用程序和协议栈内核处于同一进程中,用户程序通过回调的方式执行,这样,用户程序和协议栈内核出现了 栈内核处于同一进程中,用户程序通过回调的方式执行,这样,用户程序和协议栈内核出现了
相互制约的关系,因为用户程序执行的时候,内核-直处于等待状态,等待用户函数返回一个 相互制约的关系,因为用户程序执行的时候,内核-直处于等待状态,等待用户函数返回一个
处理结果再继续执行。如果用户程序的计算量很大,执行时间很长,则协议栈代码就- - .直得不 处理结果再继续执行.如果用户程序的计算量很大,执行时间很长,则协议栈代码就-.直得不
到执行,协议栈接收、处理新数据包效率会受到直接的影响。最严重的后果,如果发送方的数
据包发送速率很快,则协议栈会因为来不及处理而出现丢包的情况,这将导致不可原谅的错误。
这些缺点使Raw/Callback API不适合在多任务、交互数据量大、数据处理时间开销长等场合。
2、Netconn API
它的出发点是上层已经预知了协议栈内核的部 (顺序API)正是基于上述特点而设计,它的出发点是上层已经预知了协议栈内核的部分结构,API 可以使用这种预知来避免数据拷贝的出现。协议栈API同BSD socket 具有很大分结构,api可以使用这种预知来避免数据拷贝的出现.协议栈api同同Socket具有很大相似性,它们遵循了极为相似的编程步骤,但前者工作在一个更低的层次,用户进程可以直接 相似性,它们遵循了极为相似的编程步骤,但前者工作在一个更低的层次,用户进程可以直接操作内核进程中的数据包数据。 操作内核进程中的数据包数据.
3、Socket API
总之,虽然socket接口为用户使用LwIP协议栈提供了捷径,也为不同网络应用程序的移 总之,虽然套接字接口为用户使用lwIP协议栈提供了捷径,也为不同网络应用程序的移植提供了方便,但是LwIP中的Socket API并不适合用在实际项目开发中。