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

如何捕获客户端发送至STM32F767 TCP服务器的TCP数据包

STM32F767 TCP服务器数据捕获问题修复

核心问题分析

你的代码能返回ACK但无法捕获数据,主要是以下几个关键错误:

  • 空的tcp_echoserver_accept回调:新连接建立后,没有为该连接绑定接收回调,导致数据到达时无法触发recv_callback
  • 主循环中错误地给监听PCB设置recv_callback:监听状态的TCP PCB不需要接收回调,只有已建立连接的新PCB才需要
  • 未释放pbuf:接收数据后未释放数据包缓冲区,会引发内存泄漏
  • 未处理recv_callback中的错误参数:比如连接关闭时p会为NULL,需要做相应处理

修改后的完整代码

/* USER CODE BEGIN 0 */
extern struct netif gnetif;
struct tcp_pcb* tcp_echoserver_pcb;
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
ip_addr_t myIPADDR;
IP_ADDR4(&myIPADDR, 192, 168, 33, 1);

tcp_echoserver_pcb = tcp_new();
err_t err = tcp_bind(tcp_echoserver_pcb, &myIPADDR, 8);

if(err == ERR_OK)
{
    tcp_echoserver_pcb = tcp_listen(tcp_echoserver_pcb);
    tcp_accept(tcp_echoserver_pcb, tcp_echoserver_accept);
}
/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    ethernetif_input(&gnetif);
    sys_check_timeouts();
}
/* USER CODE END 3 */
}

err_t tcp_echoserver_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
{
    // 为新连接设置接收回调
    tcp_recv(newpcb, recv_callback);
    // 设置连接参数(如果需要传递自定义数据)
    tcp_arg(newpcb, NULL);
    return ERR_OK;
}

err_t recv_callback(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
    // 处理错误或连接关闭情况
    if (err != ERR_OK || p == NULL)
    {
        tcp_close(tpcb);
        tcp_recved(tpcb, 0);
        return ERR_OK;
    }

    // 这里可以留存捕获到的数据,比如复制到自定义缓冲区
    // 示例:将pbuf中的数据复制到全局数组
    // memcpy(your_buffer, p->payload, p->len);

    // 发送应答(原逻辑保留)
    tcp_write(tpcb, p->payload, p->len, TCP_WRITE_FLAG_COPY);
    tcp_output(tpcb);

    // 通知TCP栈已处理数据
    tcp_recved(tpcb, p->len);
    // 释放pbuf,避免内存泄漏
    pbuf_free(p);

    return ERR_OK;
}

关键修改说明

  • 完善accept回调:在tcp_echoserver_accept中为新建立的连接newpcb绑定recv_callback,这是触发数据接收的核心步骤
  • 移除主循环中的错误设置:删掉主循环里的tcp_arg和tcp_recv调用,这些操作不应该在监听PCB上执行
  • 添加pbuf释放逻辑:在recv_callback末尾调用pbuf_free(p),释放数据包占用的内存
  • 错误处理:增加对err和p的判断,处理连接异常关闭的情况
  • 数据留存示例:在注释中添加了将数据复制到自定义缓冲区的示例,你可以根据需求替换成自己的存储逻辑(比如保存到数组、SD卡等)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 04:22:57