一、前言
LwIP协议栈是TCP/IP协议的一种实现,由于其轻量级的特性,一般用于资源比较有限的嵌入式设备中,本文是学习了野火的LwIP教程之后做了一些学习总结,主要讲解LwIP协议栈包含的功能,如有侵权,请联系本人。
LwIP源码可以直接到官网下载:LwIP官网
1.进入LwIP官网
2.进入下载界面
如下图,进入下载区可以看到lwip和contrib两种压缩包,lwip是LwIP协议栈的源码实现;contrib不仅仅有LwIP源码,还包括一些demo,比如http客户端等。
二、LwIP简介
LwIP(Light weight IP)是一种轻量级的TCP/IP协议栈,其设计初衷是用少量的资源消耗实现一个较为完整的TCP/IP协议栈,有无操作系统均可运行。LwIP 具有主要特性:
1. 支持 ARP 协议(以太网地址解析协议)。
2. 支持 ICMP 协议(控制报文协议),用于网络的调试与维护。
3. 支持 IGMP 协议(互联网组管理协议),可以实现多播数据的接收。
4. 支持 UDP 协议(用户数据报协议)。
5. 支持 TCP 协议(传输控制协议),包括阻塞控制、 RTT 估算、快速恢复和快速转发。
6. 支持 PPP 协议(点对点通信协议) ,支持 PPPoE。
7. 支持 DNS(域名解析)。
8. 支持 DHCP 协议,动态分配 IP 地址。
9. 支持 IP 协议,包括 IPv4、 IPv6 协议,支持 IP 分片与重装功能,多网络接口下的数据包转发。
10. 支持 SNMP 协议(简单网络管理协议)。
11. 支持 AUTOIP,自动 IP 地址配置。
12. 提供专门的内部回调接口(Raw API),用于提高应用程序性能。
13. 提供可选择的 Berkeley 接口 API,即 Socket 套接字 (在多线程情况下使用) 。
三、LwIP的优缺点
1. 资源开销低,流程运行只需要40K的代码空间和几十K的内存空间;高度可剪裁,任何不需要的功能都可以通过宏编译选项去掉;LwIP有自己的内存管理策略和数据包管理策略,因此内核数据包处理很高效。
2.几乎支持TCP/IP中所有常见的协议,并且实现了一些常见的应用程序,比如:DHCP客户端、DNS客户端、HTTP服务器、MQTT客户端、TFTP服务器、SNTP客户端等。LwIP相对于其他嵌入式TCP/IP协议栈(uC-TCP/IP、FreeRTOS-TCP等)历史比较悠久,且经过更多的验证和测试,所以被广泛使用在嵌入式网络设备中。而且开源、免费。
3.对处理器和操作系统相关的地方进行了抽象,可以方便的进行跨处理器和操作系统的移植,源代码全部用C实现。提供3种编程接口:RAW API 、NETCONNN API 、Socket API,用户根据实际需要和他们各自特点选择使用。
缺点:由于面向资源有限的嵌入式设备,没有完整的实现TCP/IP协议栈,但是对于物联网的大部分场景已经足够了。
四、LwIP协议栈移植
4.1 LwIP内核
LwIP内核由多个模块组成,包括:TCP/IP协议栈的各种协议、内存管理模块、数据包管理模块、网卡管理模块、网卡接口模块、基础功能类模块、API模块。
4.2 LwIP内核的三种编程接口
RAW/Callback API
优点:有无操作系统均可使用,通过回调的方式可以提高应用程序的效率,节省内存开销(用户程序和内核程序处于同一个线程中,节省了任务切换和任务间通信的开销)。
缺点:利用回调函数开发应用程序,实现过程比较复杂,可读性差;应用程序和内核程序处于同一线程,如果应用程序占用时间过长,会影响内核程序的执行,导致丢包等问题。
NETCONN API
优点:在操作系统环境下,基于IPC机制实现,将内核程序和应用程序分离为独立的线程,LwIP内核线程只负责数据包的TCP/IP封装和拆封,应用程序负责处理应用数据,因此相对于RAW/Callback API的方式提高了协议栈对数据包的处理效率。
对网络连接进行了抽象,简化了编程工作,用户可以像操作文件那样操作网络连接,而且通过内核的pbuf、netbuf结构体来传递数据,避免了数据包在内核和应用程序之间的拷贝,
缺点:需要依赖操作系统,且IPC机制(信号量,邮箱)、任务切换需要耗费时间和内存,效率也比回调函数方式低。
虽然可以通过类似操作文件那样去操作网络连接,但是用户操作的参数是内核的相关结构体,需要用户对LwIP使用的数据结构有一定了解,不像操作文件直接读写数组那么简单。
SOCKET API
优点:基于NETCONN API 实现,进行了更高级的抽象,操作更加简单易用,有很好的移植性。
缺点:内核程序和应用程序之间存在数据拷贝,降低了数据处理的效率。
4.3 LwIP协议栈移植步骤
LwIP移植又可分为有操作系统移植和无操作系统移植,有操作系统移植步骤如下:
1.底层移植:时钟systick 中断的实现,tick->ms的转换,网卡收发线程的实现,操作系统接口的适配 ;
2.基于上面底层和操作系统的移植工作,要使LwIP跑起来,还要初始化,包括:调用lwip_init()初始化内核(内核自动创建tcpip_thread线程),挂载网卡,设置默认网卡;
3.移植完成后用电脑ping开发板测试。
备注:
a. 以太网的最大传输字节一般是1500,在IP层决定是否对数据包进行分片处理,因为链路层不提供任何差错处理机制;
b. 挂载网卡:将描述网卡的结构体通过netif_add()挂载到netif_list链表上;
c. 几种内存分配策略 :动态内存池管理、动态内存堆管理(分两种:1.C标准库自带,2.LwIP自身实现的,两者通过宏选择);
d. 在操作系统环境下,LwIP作为一个线程运行,初始化LwIP的时候,内核自动创建这个线程;
五、协议栈分层
5.1 TCP/IP协议分层
5.1.1 TCP/IP五层模型
TCP/IP是一个庞大的协议族,包含众多协议,其分层方式有2种,一种是OSI七层模型,另一种是TCP/IP五层模型;由于OSI七层模型的分层过于理想化不容易实现,以及一些历史原因,现在大多数协议栈实现都是基于TCP/IP五层模型,分层模型如下:
做应用开发时,我们对应用层,传输层,网络层比较了解,链路层和物理层就比较偏底层了,其功能如下 :
物理层:定义了传输介质、编码规则、冲突检测(星型网络代替总线型网络,冲突检测机制)。
MAC层:是数据链路层的下半部分,负责与物理层的数据交接,上层数据经过MAC层发送给物理层时,MAC层会将上层数据组成MAC数据包,MAC数据包内容有:前导字段、帧起始定界符、目标地址,源地址、数据包类型、数据域、填充域、校验和域。
5.1.2 LwIP协议栈的结构
TCP/IP有很清晰的层次结构,但是LwIP没有采用明确的分层结构,原因是LwIP协议栈一般是用于资源有限的嵌入式系统中,为了提高传输效率,减少空间占用,各层会极力避免数据拷贝,所以LwIP协议栈实现的时候就会假设各层之间的资源(部分数据、结构体以及实现原理)是互相可见的,也就可以共享,避免了标准TCP协议栈严格分层思想导致的层层拷贝浪费资源。缺点是:对使用者要求比较高,使用不正确可能会导致协议栈不能正常工作。
5.2 网络层协议简介
5.2.1 ARP协议
ARP协议即地址解析协议,划分为网络层,基本功能是通过目标设备的IP地址查询目标设备的MAC地址,MAC地址:6个字节,固化在网卡ROM,6个字节,前3个代表不同的厂家,是IEEE的注册管理机构给不同厂家分配的,区分不同的厂家,后3个字节由厂家自行分配。
以太网帧结构如下,目标mac地址用于过滤,只有网卡收到数据帧的目标MAC地址是自身的MAC或MAC广播地址,就会将该帧的数据字段的内容传递给网络层,否则就丢弃。以太网帧中MAC地址分为单播地址、多播地址、组播地址。以太网计算向网络层提供不可靠的无连接服务,网卡发送数据时,不会事先通知目标网卡,目标网卡也不会回复确认。网络层发送数据只需要知道目标主机的IP地址,链路层(网卡)发送数据只需知道对方的MAC地址。ARP的作用就是提供地址动态解析服务把32位IP映射为48位的MAC地址,将上层应用和底层隔离开。
ARP缓存表:
缓存表是ARP协议中一个核心概念。每台主机或路由器在其内存中都有一个ARP缓存表。表中记录了<IP地址,MAC地址>对,保存了主机最近运行时,获得的其他主机IP地址和MAC地址的映射关系。ARP表包含一个TTL(寿命)值,表示从表中删除每个映射的时间,从一对映射关系放置到ARP表开始计时,过期时间一般是10分钟;ARP协议的本质是对缓存表的建立、更新、查询,学习ARP协议需要了解以下几个流程:
1.ARP协议流程
2.数据包发送流程
3.数据包接收流程
5.2.2 IP协议
IP协议(Internet Protocol)又称网际协议,处于网络层,是整个TCP/IP协议栈的核心协议,IP协议负责将数据从源主机发送到目的主机,IP地址就是唯一识别码;同时IP层有可能对发送数据进行分片,对接收数据进行重装。IP协议是不可靠,无连接的,IP数据报首部有一个TTL字段,当数据报每被转发一次,TTL值就减1,当TTL为0时,路由器或主机就会丢弃该数据报。
IP地址分类编址:设计者把IP地址分为A、B、C、D、E五类,每一类地址都决定了其中IP地址的一部分组成。分类编址格式如下:
各类IP地址的特点及适用范围总结如下:
注意点:
1.网络号和主机号全为1的地址是受限广播地址,这类数据包会被整个网络接收。路由器禁止转发目的地址为255.255.255.255的广播包,这类数据只能在局域网中,因为如果这类地址被转发到整个网络,将是灾难性的。
2.主机号全为1的地址是直接广播地址,代表该网络内的所有主机,可以向网络内的所有主机发送数据,A、B、C三类地址的广播地址结构如下:
A类:xxx.255.255.255
B类:xxx.xxx.255.255
C类:xxx.xxx.xxx.255
3.多播地址属于分类编址中的D类地址,只能用于目的地址
4.127网段的所有地址都称为环回地址,主要用来测试网络是否正常,比如ping 127.1.1.1 可以测试本地TCP/IP协议是否正常。
5.IP地址4个字节全为0即0.0.0.0 是本网络本主机,只能作为源IP地址,用在设备刚启动不知道自己IP地址的情况下。
局域网与广域网示意图如下:
局域网如何和广域网通信?
路由器有一个内部地址与一个外部地址,内部地址用于局域网通信,内部地址对于广域网是不可见的;外部地址用于广域网通信,外部地址是运行商分配的;当电脑用户访问外网(比如百度)时,路由器收到电脑的请求,也就是局域网的数据报时,会为这个数据报分配一个路由器内部的NAT端口,同时路由器会将原始IP数据报中的源IP地址和源端口号通过NAT转换表转换成一个有效IP地址与端口号,这个有效IP就是外部地址。
5.2.3 ICMP协议
ICMP :Internet Control Message Protocol ,因特网控制报文协议,主要用途是差错报告和查询(比如ping)。由于IP协议是不可靠,无连接的,IP协议不保证数据是否到达,ICMP就是为了提高数据交付的准确性而产生的。交付数据时,如果由于网络,链路不通等原因导致数据无法到达目的主机,就会通过ICMP返回一个差错报文,那么源主机就能得到反馈,然后决定下一步是放弃还是重发。ICMP通常被认为是IP的一部分,但是从体系结构上来讲是位于IP层之上,ICMP的报文是作为IP数据包数据区的内容。
差错报文和查询报文的类型如下:
5.3传输层协议简介
传输层协议有TCP、UDP两种,TCP是面向连接的协议,UDP是无连接的协议,通常认为TCP提供可靠的传输,UDP是不可靠的;TCP建立连接需要三次握手,断开连接需要四次挥手。一台主机可能只有1个IP但是一般都有多个端口号,IP是用来识别主机,端口号是用来区分组件中的不同服务,比如Web服务,HTTP服务。
5.3.1 TCP协议
TCP协议(Transmission Control Protocol ,传输控制协议),具有以下特性:
1.面向连接的协议,数据传输前需要在发送端和接收端建立连接。
2.具有确认和重传机制,发送端发出数据后会启动定时器等待接收方确认,超时没有收到接收端的确认就判定发送失败,然后进行报文重传。
3.具有缓冲机制(由于发送端的数据可能是分成若干个数据报发送的,且不是同时到达,需要在缓冲区将这些数据报组合成完整的数据再递交给应用层),发送端和接收端都有缓冲机制,发送端缓冲有两个作用:
1)发送的数据很小时,不会立即发送数据,而是将数据放在缓冲区,等数据量足够大了再发送,这样可以提高发送效率。
2)发送端发出数据后不会立即删除,而是存放在缓冲区,当收到接收端的确认后再删除。
4.全双工通信:建立连接后,发送方和接收方都可以互相发送数据,如果其中一个方向断开连接,那么此时就变成半双工的了。
5.流量控制: 如果发送方发的太快太多,就可能会导致接收方缓冲区溢出。TCP提供的流量控制服务就是为了解决接收区缓冲区溢出的问题,具体实现是通过维护一个滑动窗口的变量来提供流程控制,滑动窗口大小就是接收端能处理的数据大小。
6.差错控制:TCP协议会通过校验和检验数据的正确性、接收到数据后会将重复的报文丢弃,将乱序报文重组,丢失的报文会请求重发,因此TCP往上应用层递交的数据是顺序的、无差错的完整数据。
7.阻塞控制:如果从一个大的管道(比如快速局域网)向一个较小的管道(如一个较慢的广域网)发送数据就会发生拥塞,或者多个输入流同时到达一个路由器,而路由器的输出流小于这些输入流总和时也会发生拥塞。在网络拥塞的情况下调整发送方的发送速度,这种对发送方的控制被称为拥塞控制。
5.3.2 UDP协议
UDP协议,(User Datagram Protocol,用户数据报协议),是一种无连接,不可靠的协议,没有数据排序处理、流量控制、拥塞机制,流量控制等功能,接收端也不会返回应答报文。虽然有以上缺点,但是由于没有握手,重传,拥塞等机制,所以速度相对较快,而且支持一对一,一对多,多对多,多对一的通信,UDP一般用于对传输速度有要求,并且可以容忍差错的场景。
5.4应用层协议简介
应用层常见的协议有MQTT、HTTP、COAP等,这些应用层协议都是基于传输层的。
5.4.1 HTTP协议
HTTP协议,(Hyper Text Transfer Protocol,超文本传输协议), 特点如下:
1.HTTP允许传输任意类型的数据对象,类型通过Content-Type标记
2.无连接,HTTP1.1 以前,每进行一次HTTP通信都需要断开一次TCP连接,这样很耗费资源 ;HTTP1.1 以后解决了这个问题,只要任意一端没有明确提出断开连接,就保持连接状态,减少了重复断开连接的开销。
5.无状态,协议对事务处理没有记忆能力,HTTP不能根据之前传输的数据进行本次的请求处理,如果用到之前的数据就需要重传,增大了数据传输量,但是对服务器来说应答比较快;为了解决这个问题,引用了Cookie技术,将之前的状态存储在客户端中。
HTTP报文包括3部分:起始行、首部、数据主体。
5.4.2 MQTT协议
1. MQTT协议(Message Queuing Telemetry Transport,消息队列遥测传输协议),是运行在TCP协议上的应用层协议。
协议中有3种身份:发布者,服务器,订阅者,其中服务器又被称为Broker(消息代理),MQTT通信模型如下:
2. 发布订阅模型解除了应用程序的耦合,发布者发布的消息可以被多个订阅者订阅;服务器位于发布者和订阅者之间,功能如下:
1)接受客户端的网络连接请求,
2)接受客户端发布的应用消息,
3)处理客户端的订阅和取消订阅请求
4)转发应用消息给符合条件的已订阅客户端(包括发布者本身)
3. MQTT中有两个关键元素:消息主题和服务质量 ,发布者向指定的的消息主题发布消息,订阅了这个消息主题的客户端就可以收到消息,服务质量分3个等级:
1)QoS0 :最多发送一次消息,接收者不回应,发送者不重发;
2)QoS1 :最少发送一次,需要接受者发送PUBACK报文确认;
3)QoS2 :仅发送一次,这是最高的服务质量,消息丢失和重复都是不可接受的;
5.4.2 COAP 协议
1. CoAP是Constrained Application Protocol 的缩写,它是一种应用于互联网的传输协议,之所以称之为受限的协议,主要是指在终端节点和网络能力两个方面受限;为了使受限环境与互联网环境之间的互联变得简单,COAP在设计时刻意模仿了HTTP的设计,特别是和HTTP一样都采用了RESTFUL的接口设计方式。COAP的上层是具体的物联网应用,下层是UDP协议。
2. COAP优点:
1)满足M2M需求的受限网络协议;
2)基于UDP,可支持单播和组播;
3)支持异步的消息交互;
4)简洁的报文头设计;
5)支持URI和Content-type;
6) 支持简单的代理和缓存;
7)支持与HTTP的无状态映射;
8)安全机制采用DTLS
3.交叉代理
CoAP协议中,交叉代理是指从HTTP到CoAP或者反向的协议翻译,CoAP可以理解为HTTP的一个功能子集,实现了从CoAP到HTTP的翻译,就可以使用CoAP的客户端访问HTTP服务器资源,反之亦然。