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

TI-RTOS中NDK_recv接收缓冲区strchr匹配换行符异常问题

问题根源分析与修复方案

核心错误点

  1. 消息长度计算错误:你用i = bp - buffer - 1计算消息长度时多减了1。bp指向换行符\n,从buffer起始到\n前的有效字符数应该是bp - buffer,而非减1——这会导致每条消息少复制最后一个字符。
  2. 未维护处理偏移量:处理完一条消息后,你没有更新待处理数据的起始位置,后续复制操作始终从buffer的最开头取数据,而非从上一条消息结束的位置(bp+1)开始。这直接导致后续消息复制时包含了之前的换行符,触发你看到的strchr(ac.recv, 10)非空的情况。
  3. 边界条件遗漏:仅当n>1时才处理数据,若recv返回1(比如仅收到一个\n),会直接丢弃该数据;同时未处理buffer末尾无换行符的剩余数据,这部分会丢失。

修正后的代码示例

static char leftover[sizeof(buffer)]; // 保存上一次未处理完的剩余数据
static size_t leftover_len = 0;

n = NDK_recv(s, buffer + leftover_len, sizeof(buffer) - leftover_len, 0);
if (n > 0)
{
    size_t total_len = leftover_len + n;
    buffer[total_len] = '\0'; // 确保字符串终止
    
    size_t offset = 0;
    char *bp = strchr(buffer + offset, 10);
    
    while (bp != NULL)
    {
        size_t msg_len = bp - (buffer + offset); // 正确计算消息长度
        // 确保不超过ac.recv的容量,假设ac.recv有固定大小,比如MAX_RECV_LEN
        size_t copy_len = (msg_len < sizeof(ac.recv)-1) ? msg_len : sizeof(ac.recv)-1;
        
        strncpy(ac.recv, buffer + offset, copy_len);
        ac.recv[copy_len] = '\0'; // 手动终止字符串
        
        Mailbox_post(m_sll_in, &ac, BIOS_NO_WAIT);
        
        offset = (bp - buffer) + 1; // 更新偏移到当前换行符的下一个位置
        bp = strchr(buffer + offset, 10);
    }
    
    // 保存未处理完的剩余数据到leftover
    if (offset < total_len)
    {
        leftover_len = total_len - offset;
        memmove(leftover, buffer + offset, leftover_len);
    }
    else
    {
        leftover_len = 0;
    }
}

关键改进说明

  • 新增leftover缓冲区保存未处理完的剩余数据,避免跨recv调用的数据丢失。
  • 用offset变量维护当前处理的起始位置,确保每条消息都从正确的位置开始复制。
  • 修正消息长度计算逻辑,避免少复制字符。
  • 增加对ac.recv容量的判断,防止缓冲区溢出。
  • 修复边界条件,处理n=1的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 13:49:53