TCP客户端接收服务端第二次返回消息出现内容拼接问题原因是什么?
问题根因分析
核心问题
该问题完全由客户端代码对接收缓冲区的处理逻辑错误导致:调用recv接收TCP数据后,没有手动在接收内容末尾添加字符串结束符\0,C语言中字符串操作(如printf输出)依赖\0判断字符串结束,缺少结束符会导致读取到缓冲区中残留的历史数据。
异常输出原理
- 第一次交互时服务端返回
yellow,共6字节数据,客户端recv成功后,recvline数组的前6位被填充为y、e、l、l、o、w。此时栈内存的recvline数组第7位恰好为\0(栈内存初始值巧合),因此printf正常输出yellow。 - 第二次交互时服务端返回
red,共3字节数据,客户端recv成功后,仅覆盖了recvline数组的前3位为r、e、d,数组第4~6位仍然残留上一次接收的l、o、w。由于没有手动在第4位写入\0,printf从数组首地址开始读取时,会一直输出到内存中原有\0的位置,最终打印出redlow。
对疑问的答复
该现象不是recvline把两次TCP接收的内容拼接在一起,和TCP粘包机制无关,纯粹是客户端未正确处理字符串结束符导致的异常。
修复方案
修改客户端的接收逻辑,每次接收数据后根据recv的返回值手动补\0,同时预留一位数组空间防止越界:
// 原客户端recv相关逻辑修改为 ssize_t recv_len = recv(sockfd, recvline, MAXLINE - 1, 0); // 留1字节存储结束符 if(recv_len == 0) { close(sockfd); break; } else if(recv_len > 0) { recvline[recv_len] = '\0'; // 手动添加字符串结束符 printf("%s\n",recvline); }
内容的提问来源于stack exchange,提问作者sammy
相关产品推荐
相关产品推荐

