LwIP 提供了三种主要的 API 接口,分别针对不同的应用场景(如实时性、易用性、资源占用等),开发者可根据需求选择。三种 API 分别是:
1. RAW API(原始 API)
-
特点 :
最底层的 API,直接与 LwIP 内核交互,无操作系统依赖 ,通过回调函数(callback)处理协议栈事件(如数据接收、连接建立等)。
不使用线程,所有操作在协议栈的事件处理上下文(通常是中断或定时器回调)中完成,资源占用极低(适合内存/算力受限的嵌入式设备)。
-
核心机制 :
基于事件驱动,例如:
- 注册
recv_callback处理收到的数据; - 注册
connect_callback处理连接建立结果。
- 注册
-
适用场景 :
无 OS 的裸机系统、对资源(RAM/ROM)要求严格的嵌入式设备(如单片机)、需要最高效率和实时性的场景。
-
示例(TCP 服务器) :
通过
tcp_listen()创建监听,注册accept回调;新连接到来时,在回调中注册recv回调处理数据。
2. NETCONN API(网络连接 API)
-
特点 :
基于 RAW API 封装的半阻塞式 API ,通常与操作系统(OS)配合使用(依赖线程和信号量),提供类似"连接"的抽象(如
netconn_new()创建连接、netconn_connect()建立连接)。操作可以阻塞(等待事件)或非阻塞,通过函数返回值判断操作结果(如
netconn_recv()阻塞等待数据)。 -
核心机制 :
以"连接对象(
struct netconn)"为核心,封装了底层的 socket 操作,隐藏了回调细节,提供更直观的函数接口(如netconn_send()、netconn_recv())。 -
适用场景 :
有操作系统的嵌入式系统(如 RTOS),希望简化开发(避免直接处理回调),同时保持较好的资源效率。
-
示例(TCP 客户端):
cstruct netconn *conn = netconn_new(NETCONN_TCP); netconn_connect(conn, &server_addr, server_port); // 连接服务器 netconn_send(conn, "hello"); // 发送数据 struct netbuf *buf; netconn_recv(conn, &buf); // 阻塞接收数据
3. Socket API(BSD 兼容套接字 API)
-
特点 :
兼容 BSD Socket 标准 的高层 API,与常见的 Linux/Windows 套接字接口几乎一致(如
socket()、bind()、connect()、recv()、send()、select()等)。依赖操作系统提供线程支持,操作以阻塞/非阻塞方式进行,开发门槛最低(熟悉 BSD Socket 的开发者可快速上手)。
-
核心机制 :
在 NETCONN API 之上进一步封装,模拟标准套接字的行为,支持
select()/poll()等多路复用机制,提供最高的易用性。 -
适用场景 :
有操作系统(如 Linux、RTOS)、希望代码可移植(兼容传统 Socket 程序)、追求开发效率的场景。
-
示例(UDP 通信):
cint sock = socket(AF_INET, SOCK_DGRAM, 0); // 创建 UDP 套接字 bind(sock, (struct sockaddr*)&local_addr, sizeof(local_addr)); sendto(sock, "data", 4, 0, (struct sockaddr*)&peer_addr, sizeof(peer_addr)); char buf[100]; recvfrom(sock, buf, sizeof(buf), 0, NULL, NULL); // 接收数据
三种 API 的对比总结
| 特性 | RAW API | NETCONN API | Socket API |
|---|---|---|---|
| 依赖 | 无 OS | 需 OS(线程支持) | 需 OS(线程支持) |
| 编程模式 | 事件驱动(回调) | 半阻塞(函数调用) | 阻塞/非阻塞(类 BSD) |
| 资源占用 | 极低 | 中等 | 较高 |
| 易用性 | 低(需理解内核机制) | 中 | 高(兼容标准) |
| 实时性 | 高(无线程切换) | 中 | 中(依赖 OS 调度) |
| 典型应用 | 裸机单片机 | RTOS 嵌入式系统 | 带 OS 的嵌入式/PC |
选择时需根据系统资源、开发效率、移植性等需求权衡:资源紧张选 RAW API,追求易用性和移植性选 Socket API,中间场景选 NETCONN API。