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

为何TCP客户端停止send()后recv()始终返回-1?

TCP客户端recv()返回错误码11问题分析与解答

核心结论

TCP通信不需要send()与recv()配对执行,二者是完全独立的操作:send()负责向对端发送数据,recv()负责读取对端发来的数据,不存在必须成对调用的约束。你遇到的recv()返回-1(错误码11,对应EAGAIN/EWOULDBLOCK)的问题,和是否调用send()无关,是代码中的逻辑错误以及对socket行为的误解导致的。

具体问题排查与修复

1. 状态切换的语法错误

代码中切换状态时误用了比较运算符==,而非赋值运算符=,导致状态永远无法正确切换:

// 错误写法
state == AWAKE;
state == SLEEPING;
// 正确写法
state = AWAKE;
state = SLEEPING;

2. 字符串缓冲区未正确终止

recv()读取数据后,未在rx_buffer末尾添加字符串终止符\0,会导致strcmp()的行为未定义,可能误判消息内容:

int len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0);
if(len > 0){
    rx_buffer[len] = '\0'; // 必须添加终止符,确保字符串操作正常
}

3. 错误码11的含义与处理

错误码11对应EAGAIN或EWOULDBLOCK,表示当前socket为非阻塞模式,且没有可读取的数据。处理方式:

  • 确认服务器是否确实在持续发送数据,或数据是否已被之前的recv()读取完毕
  • 如果是阻塞socket,该错误通常不会出现,需检查是否代码或框架(如ESP-IDF)默认将socket设置为非阻塞模式
  • 非阻塞模式下,可在遇到该错误时短暂休眠后重试,避免空循环占用CPU

4. TCP连接下误用sendto()

TCP是面向连接的协议,connect()成功建立连接后,应使用send()而非sendto()(sendto()主要用于UDP无连接场景):

// 错误写法(TCP连接下冗余)
int err_socket = sendto(sock, message, strlen(message), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
// 正确写法
int err_socket = send(sock, message, strlen(message), 0);

修正后的核心逻辑示例

int state = AWAKE;
while(1){
    if(state == AWAKE){
        int err_socket = send(sock, message, strlen(message), 0);
        if(err_socket < 0){
            ESP_LOGE(TCP_TAG, "Send failed: errno %d", errno);
        }
    }

    int len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0);
    if(len < 0){
        // 区分无数据可读与真正的错误
        if(errno == EAGAIN || errno == EWOULDBLOCK){
            vTaskDelay(pdMS_TO_TICKS(100)); // 短暂休眠后重试
            continue;
        }
        ESP_LOGE(TCP_TAG, "Recv error: errno %d", errno);
        continue;
    }else if(len == 0){
        // len=0表示服务器主动关闭连接
        ESP_LOGE(TCP_TAG, "Server closed connection");
        break;
    }

    rx_buffer[len] = '\0'; // 添加字符串终止符

    if(strcmp(rx_buffer, "ON") == 0){
        state = AWAKE;
    }else if(strcmp(rx_buffer, "OFF") == 0){
        state = SLEEPING;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 04:25:17