苦于使用乐鑫官方http组件时存在一定问题,受Arduino上AsyncTCP库设计启发。本人深入学习了AsyncTCP源代码,基于ESP IDF v5.4.0平台,利用LWIP raw API设计了一个异步TCP客户端/服务器库。当前库使用ESP32C3进行测试,提供非阻塞式网络操作、事件驱动架构和资源池化管理,适用于高并发物联网场景。
- 异步连接:支持IP/域名两种连接方式
- 数据流控制:窗口大小动态调整
- ACK超时检测:可配置应答超时阈值
- 延迟确认:支持TCP延迟ACK优化
- Nagle算法:可选启用/禁用低延迟模式
- 事件回调:连接/断开/数据/错误全生命周期事件
- 事件池、连接池预分配:减少动态内存分配
- 并发控制:可配置最大backlog队列
- 连接回收:自动重置客户端状态
- 统一事件循环:单任务处理所有I/O事件
- 零拷贝设计:pbuf直接传递减少内存复制
- 线程安全队列:带互斥锁保护的事件队列
- LWIP原生集成:直接操作tcp_pcb控制块
- ESP-IDF 5.4.0+
// 最小服务器示例
#include "AsyncClient.hpp"
#include "AsyncServer.hpp"
void setup() {
AsyncServer server(8080);
server.set_connected_handler([](void*, AsyncClient* client) {
client->set_data_received_handler([](void*, AsyncClient* c, const char* data, size_t len) {
c->write(data, len); // Echo模式
});
});
server.begin();
}
- 通过IP地址建立连接:connect(ip_addr_t, uint16_t)
- 通过域名建立连接:connect(const char*, uint16_t)
- 优雅关闭/强制终止连接:close(bool force=false)
- 发送原始数据:write(const void*, size_t)
- 缓冲发送模式:add()/send()
- 手动确认接收数据:ack(size_t len)
- 启动监听:begin()
- 关闭服务器:end()
- 获取服务器状态:get_connection_state()
- 全局Nagle算法开关:set_nodelay(bool)
- ACK超时时间(ms):CONFIG_ASYNC_MAX_ACK_TIME
- 最大等待连接数:CONFIG_SERVER_BACKLOG_LEN
- 客户端对象池大小:CONFIG_CLIENT_POOL_LEN
- 事件队列深度:CONFIG_EVENTS_QUEUE_LEN
- 建议增大WatchDog超时时间,以防止多并发条件下处理超时;
- 客户端实例(服务器使用时):由服务器对象池统一管理,禁止手动new/delete
- pbuf处理:在接收回调中必须调用ack()或手动pbuf_free()
- 事件处理:由事件池自动回收,用户无需干预
- 本牛马目前仅能以业余时间开发、测试开发板只有非官方ESP32C3,软件未进行充分测试,如有问题请创建Issues;
- 如有硬件或资金上的支持,请联系;
- 添加执行权限:chmod +x ab.sh
- 运行脚本:./ab.sh -c 5 -n 200 http://192.168.1.1/index.html
/*
* Hristo Gochkov 的异步 TCP 库 (https://github.com/espressif/arduino-esp32)
* 原代码版权遵循 GNU LGPL 2.1 许可
*
* 根据本人理解,在ESP IDF v5.4.0 平台实现,当前分支由于乐鑫代码风格影响不兼容原作者的API。
* 兼容版本请使用:AsyncTCP分支
* 修改后的代码版权声明:
* Copyright (c) 2023 小林同学. All rights reserved.
* Apache License 2.0 © 2023 小林同学