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

C程序使用libcurl获取本地服务器数据时出现curl failed writing body错误

搞定Curl "failed writing body" 错误的方案

Hey,我一眼就看到问题出在哪了——你的write_data回调函数返回值不对!Curl对这个回调的返回值有严格要求,必须返回实际处理的总字节数,也就是size * nmemb,而不是你现在返回的size。当返回的数值和Curl预期的字节数不匹配时,它就会判定写入失败,抛出"failed writing body"的错误。

为啥会报错?

先看你现在的回调:

size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp) { 
    return size; 
}

这里size是单个数据块的字节大小,nmemb是数据块的数量,总字节数是两者相乘。你只返回了size,相当于告诉Curl"我只处理了1个数据块的大小",但服务器返回的数据可能分成了多个块,Curl发现数据没被完整处理,直接就报错了。

最简单的修复方案

如果只是想让请求正常完成,不需要保存返回的数据,直接返回总字节数就行:

size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp) { 
    // 告诉Curl所有数据都已处理完成
    return size * nmemb; 
}

进阶:保存返回的数据

要是你需要把服务器返回的内容存下来,可以用userp参数传递存储载体,比如动态内存或者文件指针:

示例1:存到动态内存里

// 定义一个结构体来存数据和长度
typedef struct {
    char *data;
    size_t len;
} MemoryBuffer;

size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp) {
    MemoryBuffer *buf = (MemoryBuffer *)userp;
    size_t total_bytes = size * nmemb;
    size_t new_len = buf->len + total_bytes;

    // 重新分配内存,多留一个字节存字符串结束符
    buf->data = realloc(buf->data, new_len + 1);
    if (!buf->data) {
        // 内存分配失败,返回0让Curl终止请求
        return 0;
    }

    // 把新数据复制到内存里
    memcpy(buf->data + buf->len, buffer, total_bytes);
    buf->len = new_len;
    buf->data[buf->len] = '\0'; // 确保是合法的C字符串

    return total_bytes;
}

// 在main里这么用
int main() { 
    CURL *curl; 
    CURLcode res; 
    curl_global_init(CURL_GLOBAL_ALL); 
    curl = curl_easy_init(); 

    if (curl) {
        MemoryBuffer chunk = {NULL, 0};
        curl_easy_setopt(curl, CURLOPT_URL, "localhost:3000/employees/2"); 
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); 
        // 把我们的内存结构体传递给回调
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &chunk); 

        res = curl_easy_perform(curl); 

        // 这里可以用chunk.data拿到返回的内容
        if (res == CURLE_OK && chunk.data) {
            printf("Response: %s\n", chunk.data);
        }

        // 用完记得释放内存!
        if (chunk.data) free(chunk.data);
        curl_easy_cleanup(curl); 
    }
    curl_global_cleanup(); 
    return 0;
}

示例2:直接存到文件

size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp) {
    FILE *fp = (FILE *)userp;
    // 直接用fwrite返回写入的数量,和Curl预期的一致
    return fwrite(buffer, size, nmemb, fp);
}

// main里的用法
int main() { 
    CURL *curl; 
    CURLcode res; 
    curl_global_init(CURL_GLOBAL_ALL); 
    curl = curl_easy_init(); 

    if (curl) {
        FILE *fp = fopen("response.txt", "wb");
        if (fp) {
            curl_easy_setopt(curl, CURLOPT_URL, "localhost:3000/employees/2"); 
            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); 
            curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); 

            res = curl_easy_perform(curl); 

            fclose(fp);
        }
        curl_easy_cleanup(curl); 
    }
    curl_global_cleanup(); 
    return 0;
}

最后再检查俩点

  • 先确认你的本地服务器localhost:3000真的正常跑着,用命令行curl localhost:3000/employees/2测试下,看看能不能拿到数据。
  • 别忘了在请求结束后调用curl_easy_cleanup(curl)和curl_global_cleanup(),不然可能会有内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:24:35