目录

摘要:

1.介绍

2.协议分层

3.综述

4.进程模型

5.操作系统仿真层

6.缓冲与存储管理

6.1包缓冲----pbufs

6.2内存管理


摘要:

LWIP是TCP/IP协议栈的实现。LWIP协议栈关注于减少内存的使用和代码尺寸,从而使得LWIP适用于像嵌入式系统这样资源非常有限的小客户端。为了减少对处理能力和内存的要求,LWIP使用一个不需要任何数据复制的剪裁后的API。

这篇文章将描述LWIP的设计与实现。协议的实现以及像内存与缓冲管理这样的子系统中用到的算法与数据结构在这里都有描述。另外,这里也包括LWIP API的使用参考和一些使用LWIP的代码实例。

1.介绍

纵观过去的几年,连接计算机以及支持计算的设备到无线网络的需求在稳步增长。计算机正在越来越无缝的集成于每日所见设备中的,并且价格呈飞速下降趋势。同时,无线网络技术,像蓝牙[HNI+98]和IEEE802.11bWLAN[BIG+97],正在浮现。这在保健事业、安全与保密、传输以及工业处理等领域产生了许多新的让人感兴趣的局面。像传感器这样的小设备就能够连接到像全球Internet这样已经存在的网络基础设施,并且能够在任何地方进行监控。

网络技术已经证明,它自己的灵活性足够应对过去十几年不断变化着的网络环境。比起最初的像ARPANET这种低速的网络,当今的网络技术可以运行于各种不同的链路上,而这些链路不管是在带宽还是位错误率等特征上有很大的不同。由于大量的网络应用程序使用现有的网络技术,所以将已存在的网络技术运用于日后的无线网路中具有巨大的优势。同样,全球Internet的广泛的互联也是一种巨大的鼓励。由于像传感器这样的小设备常常需要较小的物理尺寸和便宜的价格,所以,一个Internet协议栈的实现就必须面对有限的计算和存储资源。本文就描述了一个小的TCP/IP协议栈的设计与实现,称之为LWIP,它足够小,因而可以用于很小的系统中。

本文的架构如下:2、3和4三节是对LWIP协议栈的综述,第5节描述操作系统仿真层,第6节描述存储与缓冲管理,第7节介绍了抽象LWIP的网络接口,8、9和10三节介绍了IP、UDP和TCP协议的实现,11、12 节描述了如何与LWIP接口并介绍了LWIP的API,13、14节分析具体的实现。最后,15节提供了使用LWIP的API的参考并在17、18节中给出代码示例。

2.协议分层

TCP/IP协议栈中的协议是基于分层的设计,每一层解决通信中的一部分相对独立的问题。这种分层可以帮助设计与实现协议,因为每一个协议都可以相对于其他协议独立的实现。尽管如此,严格的按照分层的方式来实现协议,会导致这样一种情况出现,那就是协议层之间的通信会降低整体的性能[Cla82a]。为了克服这些问题,一个协议内部的某些方面可以让其他协议了解。但是必须注意到,只有重要的信息才可以在层之间共享。

由于较低层协议之间或多或少的交叉,几乎所有的TCP/IP的实现都保持应用层与较低协议层的严格区分。在大部分操作系统中,较低的协议层也作为操作系统内核的一部分而加以实现,并带有和应用程序层进程进行通信的入口点。应用程序对于TCP/IP的实现呈现一种抽象的观点,在那里,网络通信与内部进程通信或者文件I/O并没有太大的不同。这意味着由于应用程序并没有意识到底层协议所使用的缓冲机制,因而它不能够使用这些信息,比如利用频繁使用过的数据重复利用缓冲区。也就是说,当应用程序发送数据时,在它们被网络代码处理之前,数据必须从应用进程空间复制一份到内部缓冲区。

对于像目标系统为LWIP这样的小系统中的操作系统,在内核与应用进程之间几乎没有保持一个严格的保护栅栏。这就允许使用共享内存这种简单的方案实现应用程序与底层协议之间的通讯。特别的,可以使应用程序意识到底层所使用的缓冲捕获机制。这样,应用程序可以更加有效的重复利用缓冲区。同样,由于应用进程可以与网络代码使用同一个内存缓冲区,所以,应用程序可以直接的读写内部缓存,从而节省了复制数据的性能花费。

3.综述

就像许多其他TCP/IP的实现,分层的协议设计也被用作指导来设计LWIP的实现。每一个协议被作为一个独立模块来设计实现,通过一些函数作为进入其他协议的入口点。尽管这些协议是独立实现的,但如上所述,为了提升性能,不管是处理速度还是内存占用,仍然有一些违反分层的做法。比如,当确认一个传送进来的TCP段的校验和时,还有,当多路分解一个段时,这个段的源和目的的IP地址必须被TCP模块知道。在这里不采用通过函数调用将这些地址传给TCP的做法,而是让TCP模块意识到IP头的数据结构,从而能够自己来设法得到这些信息。

LWIP由许多模块组成。除了实现TCP/IP协议栈的模块(IP、ICMP、UDP和TCP),一些支持模块也被实现了。支持模块包括操作系统仿真层(在第5节描述),缓冲和内存管理子系统(第6节),网络接口函数(第7节),以及为计算Internet校验和的函数。LWIP也包括一个抽象的API,在12节讲述。

4.进程模型

协议实现的进程模型将系统分解为不同的进程的方式来进行讲述。被用来实现通信协议的进程模型将使得每一个协议以一个单独的进程的方式来运行。通过这种模型,严格的协议分层被强化,不同协议之间的通信点必须严格限制。这种方式有它自身的优点,像协议可以在运行时加载,理解代码以及调试将变得更加容易。除此之外,它也有缺点。就像先前所叙述的,严格的分层并不总是实现协议的最好方式。更重要的是,对于各个层之间的访问,一个上下文开关必须提供。对于一个传送进来的TCP段来说,这将意味着必须有三个上下文开关,从设备驱动到网络接口,从IP进程到TCP进程,最后到应用进程。在几乎所有的操作系统中,一个上下文开关是不小的花费。

另外一种通常的方法是让协议之间的通信存在于操作系统内核中。一旦内核实现了协议之间的通信,应用进程与协议之间的通信就可以通过系统调用来实现。虽然协议之间的通信彼此之间并没有严格的划分,但是,可能要使用到穿过不同协议层的技术。

LWIP使用进程模型,所有协议存在于一个单进程中,并且独立于操作系统内核。应用程序可能存在于LWIP进程中,或者存在于独立的进程中。TCP/IP协议栈与应用程序之间的通信或者通过函数调用来实现,比如应用程序与LWIP共享一个进程;或者通过一个更加抽象的API的方式。

当然,将LWIP的实现作为一个用户空间的进程而不是在操作系统内核有它的优点和缺点。将LWIP作为一个进程主要的优点在于能够便于访问不同的操作系统。因为LWIP被设计为运行在小的操作系统上,而这样的操作系统通常都不支持交换区处理和虚拟存储,因此由于LWIP进程被交换或换页出到硬盘而不得不等待磁盘活动所造成的延时将不再是需要考虑的问题。而问题在于得到机会去服务请求之前进行调度所要等待的总的时间,但是在LWIP的设计中,并没有什么能够妨碍它以后在一个操作系统的内核中来实现。

5.操作系统仿真层

为了使得LWIP更加便携,操作系统相关的具体函数和数据结构并不直接在代码中使用,相反,当这样的功能函数需要时,操作系统仿真层会被用到。操作系统仿真层提供一个唯一的接口给操作系统服务,这些服务包括像时间、进程同步和消息传递机制。原则上讲,当将LWIP移植到其他操作系统上时,对于该特定的操作系统,仅仅需要操作系统仿真层的实现即可。

操作系统仿真层提供一个时间功能函数供TCP使用。这些由操作系统仿真层提供的计时器是至少保持200ms时间间隔的时间片,在这期间当超时发生时调用注册的函数。

进程同步机制仅提供信号量。即使信号量在下层的操作系统中不可用,它们也能够通过其他原始的同步机制像条件变量或者锁来仿真。

消息传递通过使用一个称为mailboxes的抽象调用这样一种简单机制来完成。一个mailboxes有两种操作:发送与获取。发送将不会阻塞该进程,更确切的说,发送到邮箱的消息通过操作系统仿真层被排成队列直到其他进程来取得它们。即使下层的操作系统对于邮箱没有自然的支持,他们也能够通过使用信号量很容易的实现。

6.缓冲与存储管理

通信系统中的存储与缓冲管理系统必须被很好的准备来适应缓冲区在一个较大范围内的变化,从缓冲包含有几百字节的完整的TCP段到只包含几个字节的短ICMP响应。另外,为了避免数据复制,有可能会使缓冲区中的数据内容存在于内存中,这部分内存并不由像应用程序存储区或者ROM由网络子系统来管理。

6.1包缓冲----pbufs

在LWIP内部,一个pbuf代表一个数据包,并且根据最小栈的特殊需要而设计。pbufs类似于BSD实现中所使用的mbufs。pbuf数据结构即支持动态内存分配来捕获数据包中的内容,同时,也能够使得包数据存在于静态内存。pbufs能够通过一个链连接在一起,称作pbuf链,因此通过链,一个数据包可能存在于多个pbufs中。

有三种类型的pbufs,pbuf ram、pbuf rom和pbuf pool。图一中所示的pbuf代表pbuf ram 类型的pbuf,包数据存储于由pbuf子系统管理的内存中。图二则是一个pbuf链的实例,链中第一个为pbuf ram 型的pbuf,第二个为pbuf rom型的pbuf,这意味着内存中有数据不被pbuf子系统管理。第三种类型的pbuf,即pbuf pool,在图三中可以看到,它由固定大小的pbuf构成,这些pbufs来自于由固定大小的pubf构成的池中。一个pbuf链可能包含多种类型的pbufs。

这三种pbufs都有各自不同的用途。pubf pool型的pbuf主要由网络设备驱动来使用。因为这样分配一个pbuf的操作将是迅速的,并且因此也适合于在中断捕获中使用。pubf rom型的pbuf在应用程序发送数据时使用,而这些数据定位于由应用程序管理的内存中。这些数据在pbuf被交到TCP/IP协议栈之后可能不会再被改变,因此,这种类型的pbuf主要在数据定位于rom中时使用(这也就是为什么叫pubf Rom)。预先计划到pubf rom中的数据头被存储到pbuf ram型的pubf中,并被连到pbuf rom型pbuf的开头,如图2所示。

Ram型的pubfs也在应用程序发送动态生成的数据的时候使用。在这种情况下,pbuf系统不仅给应用程序数据分配内存,同时也为预先计划好的数据头分配内存。这在图一中可以看到。包缓冲系统不可能预先知道那些头将被计划为数据,通常就假设最糟糕的情况。头的大小在编译时被配置。

本质上,输入包缓冲是pbuf pool类型的,而输出包缓冲是pbuf rom或者pbuf ram型的。

一个pbuf的内部数据结构可以通过图一到图三看出。pbuf由两个指针、两个长度域、一个标识域以及一个参考计数域构成。next域在pbuf链中用来指向下一个pbuf。payload指针指向pbuf中数据的开始。len域包含有pbuf数据内容的长度。tot_len域是当前pbuf的长度和pbuf链中其他pbuf的len域的长度之和。换句话说,tot len就是当前的len域与pbuf链中下一个pbuf的tot len中的值之和。标识域用来指示pbuf的类型,而ref域包含有一个参考计数。next和payload域是原始的指针,它们的大小取决于所使用处理器的架构。两个长度域是16位的无符号的整型数据,标识和参考计数域是4个位的宽度。整个pbuf结构的大小依赖于所使用处理器架构中指针的大小以及处理器架构中最小的可能的对齐方式。对于32位指针和4字节对齐的结构,总共的大小为16字节,而对于16位指针和1字节对齐的结构,则只需9个字节。

包缓冲模型提供了操作缓冲包的功能函数。函数pbuf_alloc()用来分配一个pbuf,它可以分配前面描述的任何一种类型的pbuf。函数pbuf_ref()用来将参考计数加一。pbuf_free()用来进行释放分配操作,它首先将pbuf的参考计数减一。当参考计数为0时,pbuf就被释放。函数pbuf_realloc()用来为pbuf瘦身,以使得它能够拥有足够的内存来满足数据存储。pbuf_hader()函数用来调节改变payload指针和长度域,以使得一个数据头能够按照计划加入到pbuf中。pbuf_chain()和pbuf_dechain()函数用来构链和拆链。

6.2内存管理

存储管理者对于pbuf的支持方案是非常简单的。它持有分配的与释放的内存相邻区域的句柄,并且能够缩减先前已分配的内存块的大小。内存管理者使用系统所有内存的一个专用的部分,这将保证网络系统不会使用所有其他可用内存,并且如果网络系统已经使用了它的所有内存其他程序的操作也不会被干扰。

在内部,内存管理者通过在每一个已分配内存块上使用一个小的数据结构来跟踪已分配的内存。这个结构体(如图4)含有两个指针用来指向其之前与之后已分配块的内存。它同样还有一个标识域用来指示分配块已经被分配了还是没有。

当在内存中查找到一个还没有被使用的分配块,并且对于分配请求而言其足够大,该内存块将被分配。这里,首次匹配原则被使用,也就是第一块满足条件的内存块将被首先使用。当一个分配块被释放时,标示域被置为0表示该内存块不再被使用,属于可分配块。为了避免碎片,之前与之后分配块的标示域将被检查,如果它们中的任何一个都没有被使用,这些块将被合并为一个更大的未使用块。

TCP/IP协议栈Lwip的设计与实现:之二_龙赤子的博客-CSDN博客

TCP/IP协议栈Lwip的设计与实现:之一相关推荐

  1. TCP/IP协议栈Lwip的设计与实现:之三

    接上文:TCP/IP协议栈Lwip的设计与实现:之二_龙赤子的博客-CSDN博客 目录 10.TCP处理 10.1概述 10.2数据结构 10.3序列号计算 10.4数据入队和传输 10.5接收段数据 ...

  2. STM32F103驱动SDIO wifi Marvell8801/Marvell88w8801 介绍(十) ---- 移植TCP/IP协议栈LWIP

    代码工程的GITHUB连接:点进进入GITHUB仓库 https://github.com/sj15712795029/stm32f1_marvell88w8801_marvell8801_wifi ...

  3. TCP/IP协议栈之LwIP(四)---网络诊断与状态查询(ICMPv4 + ICMPv6)

    文章目录 一.ICMP协议简介 1.1 ICMPv4报文功能 1.2 ICMPv6报文功能 二.PC常用网络命令 三.ICMP协议实现 3.1 ICMPv4数据报描述 3.2 ICMPv4数据报操作函 ...

  4. TCP/IP协议栈之LwIP(六)---网络传输管理之TCP协议

    文章目录 一.TCP协议简介 1.1 正面确认与超时重传 1.2 连接管理与保活机制 1.3 滑动窗口与缓冲机制 1.4 流量控制与拥塞控制 1.5 提高网络利用率的其他机制 二.TCP协议实现 2. ...

  5. 为何TCP/IP协议栈设计成沙漏型的

    前几天有人回复我的一篇文章问,为何TCP/IP协议栈设计成沙漏型的.这个问题问得好! 我先不谈为何它如此设计,我一个80后根本就没有资格去评论上世纪80年代已经臻于成熟的一个设计,我只是说一下目前的趋 ...

  6. TCP/IP协议栈之LwIP(二)---网络接口管理

    文章目录 一.网络接口层简介 1.1 物理层 1.2 逻辑链路控制层 1.3 以太网数据帧简介 二.网络接口管理 2.1 网络接口的描述 2.2 网络接口的操作 三.特殊的环回接口 更多文章 一.网络 ...

  7. 几种开源的TCP/IP协议栈分析

    1.BSD TCP/IP协议栈 BSD栈历史上是其他商业栈的起点,大多数专业TCP/IP栈(VxWorks内嵌的TCP/IP栈)是BSD栈派生的.这是因为BSD栈在BSD许可协 议下提供了这些专业栈的 ...

  8. 单片机tcp ip协议c语言,单片机TCP IP协议栈实现的原理

    对已TCP IP协议栈,我们已经说了很多关于它的原理相关的知识了.但是只有原理是不够的,在这方面我们将要举出一个实际操作实例为大家讲解,那么首先我们来看一下有关于单片机TCP/IP就是在单片机上运行的 ...

  9. 源码公开的TCP/IP协议栈在远程监测中的应用

    目前,随着互联网的发展,越来越多的工业测控设备已经将网络接入功能作为其默认配置,以实现设备的远程监控和信息分布式处理.笔者曾参与某发电机射频监测仪的开发,该设备主要用于诊断和预警发电机早期故障,并通过 ...

最新文章

  1. 利用反汇编手段解析C语言函数
  2. 【LeetCode从零单排】No28 Implement strStr()
  3. c.语言2017试卷,2017年全国计算机等级考试二级C 语言真题及答案7
  4. Chapter 3 Phenomenon——19
  5. .NET开发框架(九)-NLB网络负载平衡配置实战(视频)
  6. 被裁半年后进大厂,他咋做到的?
  7. python编写时钟代码_python Tkinter 编写时钟
  8. centos6.3安装Samba及权限
  9. SQL*Plus格式化查询结果
  10. Office | Office365 离线安装包选择安装word、ppt、excel
  11. linux显示文件后缀名命令,Linux学习笔记(ctrl命令find命令文件后缀名)
  12. linux驱动篇-Led
  13. 河南公务员写古文辞职信:陡增酒量 武功尽废
  14. P1779 小胡同学的跳板
  15. bilibili视频格式m4s批量转换为mp3,mp4
  16. lodop打印html包含图片,使用lodop.js打印控件打印table并分页等
  17. 基于vue2编写的md编辑器-Bytemd
  18. c# 开发winform控件
  19. html翻牌动画效果,js+css3翻牌动画效果
  20. python3数据分析的书籍_从零开始用Python3做数据分析

热门文章

  1. 数据挖掘学习——SOM网络聚类算法+python代码实现
  2. Eclipse oxygen 版本汉化教程
  3. 深度学习的主要应用举例
  4. 单例模式深入浅出---详细注释
  5. 【shell】实现交互|read读取键盘输入
  6. Vegas使用技巧—— 如何实现三维立体调整?
  7. 转载-【讨论】为什么不去读顶级会议上的论文?适应于机器学习、计算机视觉和人工智能
  8. 通过session爬取我要自学网会员中心的账号信息
  9. java笔试题---用*打印漏斗形,信雅达笔试题
  10. 使用cmd时cd命令失效