You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LwIP TCP接收回调异常咨询:匹配失效与乱码问题排查

TCP接收回调函数问题排查与修复

问题现象

  • 首次发送数据能正常匹配返回结果,但后续发送其他内容均返回Data could not be interpreted.
  • 返回消息伴随大量乱码,示例如下:
hello world
hello worldJwÚ: String data was sent
111
111UUU£å©2£å©2£å©2£å©2£å©2£å©2£å©2£å©2£å©2£å©2£å©2£å©2: Data could not be interpreted.
!!!
!!!UUU»Ç¯»Ç¯»Ç¯»Ç¯»Ç¯»Ç¯»Ç¯»Ç¯»Ç¯»Ç¯»Ç¯»Ç¯!eÊdmu: Data could not be interpreted.
hello world
hello world"Æ©: String data was 

问题根源

  1. 字符串无终止符:memcpy只复制了数据内容,未添加\0终止符,strcmp依赖终止符判断字符串结束,后续残留数据会导致匹配失败。
  2. 缓冲区未清空:data和msg应为全局/静态变量,每次使用前未清空,旧数据残留引发乱码。
  3. 分支代码错误:第三个分支用sprintf(data, ...)却调用tcp_write(tpcb, msg, ...),msg未被赋值,直接使用旧内容,导致逻辑错误和乱码。
  4. 潜在缓冲区溢出:使用sprintf未限制长度,可能超出缓冲区大小引发乱码。

修复后的代码

// 提前定义足够大的缓冲区,避免溢出
#define BUF_SIZE 256
static char data[BUF_SIZE];
static char msg[BUF_SIZE];

err_t recv_callback(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
    if(p == NULL)
    {
        tcp_close(tpcb);
        return ERR_OK;
    }

    // 清空缓冲区,彻底清除旧数据残留
    memset(data, 0, sizeof(data));
    memset(msg, 0, sizeof(msg));

    // 复制数据并添加字符串终止符,确保strcmp正常工作
    if(p->len < sizeof(data))
    {
        memcpy(data, p->payload, p->len);
        data[p->len] = '\0';
    }
    else
    {
        // 数据过长时截断,避免缓冲区溢出
        memcpy(data, p->payload, sizeof(data)-1);
        data[sizeof(data)-1] = '\0';
    }

    // 先确认接收,防止TCP窗口阻塞,影响后续数据传输
    tcp_recved(tpcb, p->len);

    if(strcmp(data,"111") == 0)
    {
        snprintf(msg, sizeof(msg), "%s: Integer data was sent", data);
        tcp_write(tpcb, msg, strlen(msg), TCP_WRITE_FLAG_COPY);
    }
    else if(strcmp(data,"hello world") == 0)
    {
        snprintf(msg, sizeof(msg), "%s: String data was sent", data);
        tcp_write(tpcb, msg, strlen(msg), TCP_WRITE_FLAG_COPY);
    }
    else if(strcmp(data,"!!!") == 0)
    {
        snprintf(msg, sizeof(msg), "%s: Special character data was sent", data);
        tcp_write(tpcb, msg, strlen(msg), TCP_WRITE_FLAG_COPY);
    }
    else
    {
        snprintf(msg, sizeof(msg), "%s: Data could not be interpreted.", data);
        tcp_write(tpcb, msg, strlen(msg), TCP_WRITE_FLAG_COPY);
    }

    pbuf_free(p);
    return ERR_OK;
}

关键修复说明

  • 添加字符串终止符:复制数据后手动补\0,让strcmp能正确识别字符串边界,解决后续匹配失败问题。
  • 强制清空缓冲区:每次回调开始用memset清空缓冲区,彻底消除旧数据残留引发的乱码。
  • 修正分支逻辑错误:第三个分支改为写入msg缓冲区,不再误用变量。
  • 替换为snprintf:限制写入长度,避免缓冲区溢出,提升代码安全性。
  • 调整tcp_recved位置:提前确认接收,防止TCP窗口被占满,保证后续数据正常接收。

内容的提问来源于stack exchange,提问作者confusedfresher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 13:25:01