LwIP为用户应用程序的编写提供了三种编程接口:
1.Raw/Callback API
基于该接口来实现LwIP网络编程时,协议栈与用户程序之间通信是通过回调函数来实现的。
此时用户程序和协议栈内核运行于同一个进程中,是一种最直接的利用协议栈的方法,应用程序通过函数注册的方式与内核产生联系,在内核相关事件发生时,用户函数通过回调的方式被执行。用户程序通过回调执行的方式取得协议栈中的数据。
NOTE:(1)Raw/Callback可以方便的构造出一个服务器对多个客户端的TCP并发连接。
(2)Sequential API只能通过多线程的方式来实现并发连接。
弊端:因为应用程序协议栈内核在一个线程中执行,所以两者出现相互制约,回调函数执行的时候,内核会处于等待状态,等待用户程序处理结果再执行,如果应用程序的计算量大,执行时间长,接收数据、发送数据效率会产生影响,可能出现丢包
==》该方式不适合在多任务、交互数据量大、数据处理时间开销长的应用场景使用
该方式需要使用者对内核理解透彻,不适合初学者。但是适合低成本MCU不跑os,数据交互不大的系统。
当工程师需要使用低成本联网方案时候可以理解透彻lwip内核,在此基础上开发那些下发配置,隔段时间上传产生的记录,心跳的项目使用或者数据量不大响应时间要求高的项目。当项目中一段时间或者全程需要大数据量下发和别的事务处理时候不建议使用。
2.Sequential API
该方式的实现主要由三部分组成:
(1)第一部分作为用户编程接口函数提供给用户,这些函数在用户进程中执行;
(2)第二部分驻留在协议栈内核进程中。
(3)第三部分是进程通信机制(IPC),让前两部分能够通过该部分实现同步和通信,共同为应用程序提供服务。
使用邮箱和信号量等机制,内核进程可以直接将数据递交到应用程序邮箱中然后继续执行,不必阻塞等待,邮箱对于应用程序来说就像一个输入队列。
NOTE:
(1)协议栈内核运行于进程tcpip_thread,应用程序也是一个独立的进程。
(2)协议栈API为用户提供了数据包管理函数,可以完成数据包内存申请、释放、数据拷贝等任务,应用程序使用netbuf结构来描述,组装数据包,当协议栈接收到新数据包时候,会将数据封装在一个netbuf中,并提交给应用程序,该结构只是对内核pbuf的简单封装,通过共享一个netbuf结构,两部分API就能实现对数据包共同处理。
对于接收,无论TCP还是UDP数据都是放在netbuf内提交上来;
对于发送,TCP用户只需提供待发送数据的起始地址和长度,内核会根据实际情况将数据封装在合适大小的数据包中,放入发送队列中;UDP用户需要自行将数据封装在netbuf结构中,发送函数被调用时候,内核直接将数据包中的数据发送出去。
弊端:应用程序的执行效率会有所降低,因为这其中过程设计一系列的邮箱、信号量的交互过程。
3.Socket API
LwIP的该API封装不完善,最好不要使用在开发中,且其效率比第二种还要低,新的版本不知道是否完善!!
这种API当然也是在OS中使用,编程方法和BSD一样简单。
NOTE:多线程中也能在一个线程内使用回调机制编程,优缺点和单线程的一样。