C TCP Socket使用select接收同一客户端多条消息超时问题求助
代码核心错误点
- 最根本的问题出在客户端逻辑:客户端发送第一条消息后直接调用
recv阻塞等待服务端响应,根本没有机会发送第二条消息,服务端等待5秒收不到第二条消息自然每次都触发超时。 - 客户端存在重复创建socket的冗余代码:第一次创建的socket没有被使用就被第二次创建的socket覆盖,造成资源泄漏。
- 服务端发送响应的参数完全错误:
send(sock, &result, sizeof(result), 0)中,result是指向拼接后字符串的指针,&result是指针本身的内存地址,sizeof(result)在64位系统下仅为8字节,既没有发送正确的字符串内容,也没有传递正确的长度;且超时场景下result未初始化,直接发送会触发野指针访问崩溃。 - 服务端
concat函数分配的堆内存没有释放,会造成内存泄漏。 - 两端的
send调用都存在冗余传输问题:每次都发送整个缓冲区长度的内容,而非实际字符串长度,浪费带宽且可能传输无效字符。
简易修复方案
客户端修改要点
- 删除重复的
socket创建代码 - 调整逻辑支持连续输入两条消息后再等待服务端返回,示例修改:
// 把原来的while循环改成如下逻辑即可测试 while (1) { // 输入第一条消息 printf("输入第一条消息:"); fgets(buf, BUF_SIZE, stdin); if (feof(stdin)) break; send(sock, buf, strlen(buf), 0); // 输入第二条消息 printf("输入第二条消息(5秒内完成):"); fgets(buf, BUF_SIZE, stdin); if (feof(stdin)) break; send(sock, buf, strlen(buf), 0); // 等待服务端返回 readSize = recv(sock, buf, sizeof(buf)-1, 0); if (readSize <=0 ) break; buf[readSize] = '\0'; printf("服务端返回:%s\n", buf); }
服务端修改要点
- 调整发送逻辑,超时场景下返回警告内容,正常场景发送拼接后的字符串,用完释放内存:
char *result; if (FD_ISSET(sock, &readfds)) { readSize = recv(sock, stringB, sizeof(stringB)-1, 0); if (readSize <=0 ) break; stringB[readSize] = '\0'; result = concat(stringA, stringB); printf("收到第二条消息,拼接后内容:%s\n", result); send(sock, result, strlen(result), 0); free(result); // 释放堆内存 } else { printf("超时\n"); const char *warn = "警告:5秒内未收到第二条消息"; send(sock, warn, strlen(warn), 0); }
- 移除不需要的
FD_SET(0, &readfds)代码,不需要监听标准输入的话无需添加该配置。
内容的提问来源于stack exchange,提问作者Bryce Chan
相关产品推荐
相关产品推荐

