TI-RTOS中NDK_recv接收缓冲区strchr匹配换行符异常问题
问题根源分析与修复方案
核心错误点
- 消息长度计算错误:你用
i = bp - buffer - 1计算消息长度时多减了1。bp指向换行符\n,从buffer起始到\n前的有效字符数应该是bp - buffer,而非减1——这会导致每条消息少复制最后一个字符。 - 未维护处理偏移量:处理完一条消息后,你没有更新待处理数据的起始位置,后续复制操作始终从buffer的最开头取数据,而非从上一条消息结束的位置(
bp+1)开始。这直接导致后续消息复制时包含了之前的换行符,触发你看到的strchr(ac.recv, 10)非空的情况。 - 边界条件遗漏:仅当
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
相关产品推荐
相关产品推荐

