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

C TCP Socket使用select接收同一客户端多条消息超时问题求助

代码核心错误点

  • 最根本的问题出在客户端逻辑:客户端发送第一条消息后直接调用recv阻塞等待服务端响应,根本没有机会发送第二条消息,服务端等待5秒收不到第二条消息自然每次都触发超时。
  • 客户端存在重复创建socket的冗余代码:第一次创建的socket没有被使用就被第二次创建的socket覆盖,造成资源泄漏。
  • 服务端发送响应的参数完全错误:send(sock, &result, sizeof(result), 0)中,result是指向拼接后字符串的指针,&result是指针本身的内存地址,sizeof(result)在64位系统下仅为8字节,既没有发送正确的字符串内容,也没有传递正确的长度;且超时场景下result未初始化,直接发送会触发野指针访问崩溃。
  • 服务端concat函数分配的堆内存没有释放,会造成内存泄漏。
  • 两端的send调用都存在冗余传输问题:每次都发送整个缓冲区长度的内容,而非实际字符串长度,浪费带宽且可能传输无效字符。

简易修复方案

客户端修改要点

  1. 删除重复的socket创建代码
  2. 调整逻辑支持连续输入两条消息后再等待服务端返回,示例修改:
// 把原来的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);
}

服务端修改要点

  1. 调整发送逻辑,超时场景下返回警告内容,正常场景发送拼接后的字符串,用完释放内存:
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);
}
  1. 移除不需要的FD_SET(0, &readfds)代码,不需要监听标准输入的话无需添加该配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 21:06:02