»
(008)CubeIDE实现USB外设*
(018)C99 的指针*
(019)C99 只有值赋值,没有move*
(022)POSIX线程库pthread的同步锁*
(023)POSIX线程库pthread的多线程*
(027)C99标准库中的计时与等待 *
(028)C语言中的高精度计算库GMP *
(029)C语言中的Web服务*
(030)C语言中的字符转码ICU*
(031)从几个方面显然C语言比C++效率高*
🕹️(038)LwIP Tcp Server开发例程
LwIP Tcp Server开发例程(总结自ChatGPT):
LwIP核心单线程,所有协议栈操作和回调都在一个线程中运行。
void TcpServerInit(void)
{
struct tcp_pcb *tcp_server_pcb;
tcp_server_pcb = tcp_new();
tcp_bind(tcp_server_pcb, IP_ADDR_ANY, 8080);
tcp_server_pcb = tcp_listen(tcp_server_pcb);
tcp_accept(tcp_server_pcb, TcpServerAcceptCallback); //主循环中需要不断地调用sys_check_timeouts来检查有没有新的Tcp连接的到来
}
static err_t TcpServerAcceptCallback(void *arg, struct tcp_pcb *pcb, err_t err)
{
if (pcb == NULL) {
return ERR_MEM; // 无法创建新的连接
}
tcp_accepted(pcb);// 通知 LwIP 当前连接已被接受
tcp_recv(pcb, TcpServerRecvCallback);// 注册接收数据的回调函数
return ERR_OK;
}
static err_t TcpServerRecvCallback(void *arg, struct tcp_pcb *pcb, struct pbuf *tcp_recved_pbuf, err_t err)
{
if (tcp_recved_pbuf == NULL) {
// 远程端已关闭连接
tcp_close(pcb);
return ERR_OK;
}
if (err != ERR_OK) {
// 如果发生错误,释放 pbuf 并返回错误
struct pbuf *current_pbuf = tcp_recved_pbuf;
struct pbuf *tmp_pbuf = tcp_recved_pbuf;
while (current_pbuf != NULL) {
tmp_pbuf = current_pbuf;
current_pbuf = current_pbuf->next;
pbuf_free(tmp_pbuf);
}
return err;
}
//以下处理数据
size_t total_len = tcp_recved_pbuf->tot_len;// tot_len 是链表中所有节点的 len 累加值
struct pbuf *current_pbuf = tcp_recved_pbuf;
struct pbuf *tmp_pbuf = tcp_recved_pbuf;
while (current_pbuf != NULL) {
tcp_write(pcb, current_pbuf->payload, current_pbuf->len, 1); //echo全部pbuf块数据
tmp_pbuf = current_pbuf;
current_pbuf = current_pbuf->next;
pbuf_free(tmp_pbuf);
}
tcp_recved(pcb, total_len);
//恢复收发窗口:当应用层处理完接收到的数据后,需要增加接收窗口的大小,以便继续接收新的数据
return ERR_OK;
}
最后,建议采用Unix Socket开发方式开发LwIP的socket代码。