🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
在标准的TCP/IP协议栈中,各层之间都是一个独立的模块,它有着很清晰的层次结构,每一层只负责完成该层的处理,不会越界到其他层次去读写数据。而LwIP只是一个轻量级TCP/IP协议栈,它只是一个较完整的TCP/IP协议,多应用在嵌入式领域中,由于处理器的性能有限,LwIP并没有采用很明确的分层结构,它假设各层之间的部分数据和结构体和实现原理在其他层是可见的,简单来说就传输层知道IP层是如何封装数据、传递数据的,IP层知道链路层是怎么封装数据的等等。 为什么要模糊分层的处理?简单来说就是为了提高效率,例如链路层完成数据包在物理线路上传输的封装;IP层完成数据包的选择和路由,负责将数据包发送到目标主机;传输层负责根据IP地址将数据包传输到指定主机,端口号识别一台主机的线程,向不同的应用层递交数据;但是,如果按照标准的TCP/IP协议栈这种严格的分层思想,在数据传输的时候就需要层层拷贝,因为各层之间的内存都不是共用的,在链路层递交到IP层需要拷贝,在IP层递交到传输层需要拷贝,反之亦然,这样子每当收到或者发送一个数据的时候都要CPU去拷贝数据,这个效率就太慢了,所以LwIP假设各层之间的资源都是共用的,各层之间的实现方式也是已知的,那么在IP层往传输层递交数据的时候,链路层往IP层递交数据的时候就无需再次拷贝,直接操作协议栈中属于其他层次的字段,得到相应的信息,然后直接读取传递的数据即可,这样子处理的方式就无需拷贝,各个层次之间存在交叉存取数据的现象,既节省系统的空间也节省处理的时间,而且更加灵活。例如在传输层,在计算TCP报文段的校验以及TCP在重装无需报文时,TCP层必须知道该报文的源IP地址和目的IP地址,为了得到这些信息,传输层并不是调用IP层的接口,而是直接访问数据包中的IP数据报首部,因为传输层已经知道IP层的数据报的格式及作用,直接访问读取这些信息即可。 在小型嵌入式设备中,LwIP与用户程序之间通常没有太严格的分层结构,这种方式允许用户处理数据与内核之间变得更加宽松。LwIP假设用户完全了解协议栈内部的数据处理机制,用户程序可以直接访问协议栈内部各层的数据包,可以让协议栈与用户使用同样的内存区域,允许用户直接对这片区域进行读写操作,这样子就很好地避免了拷贝的现象,当然这样子的做法也有缺陷,取决于用户对协议栈处理过程的了解程度,因为数据是公共的,如果处理不正确那就让协议栈也没法正常工作。 当然,除了标准的TCP/IP协议,还存在很多其他的TCP/IP协议,即使这些协议栈内部存在着模糊分层、交叉存取现象,但是对协议栈外部的应用层则保持着明显的分层结构,在操作系统中,TCP/IP协议栈往往被设计为内核代码的一部分,用户可以的函数仅仅是协议栈为用户提供的那些,或者直接完全封装起来,用户的操作类似于读写文件的方式进行(如BSD Socket),这样子用户就无法避免数据的拷贝,在数据发送的时候,用户数据必须从用户区域拷贝到协议栈内部,在数据接收的时候,协议栈内部数据也将被拷贝到用户区域。 严格按照TCP协议的分层思想会导致数据包在各层递交产生内存拷贝问题,影响性能。为了节省时间和空间的开销,LwIP没有遵循严格的分层机制,各层次之间存在交叉存取的现象,提高效率。 由于LwIP的内存共享机制,使得应用程序能直接对协议栈内核的内存区域直接操作,减少时间和空间的损耗。