libcurl调用WriteFunction回调后保持Pushbullet流式连接持续运行
解决libcurl对接Pushbullet流式接口后连接自动关闭的问题
我来帮你搞定这个问题!你的代码里有两个核心问题导致回调触发后连接就关闭了,咱们一步步修正,让长连接稳定跑起来:
问题根源分析
- 回调函数签名不匹配:libcurl的
CURLOPT_WRITEFUNCTION要求回调必须遵循固定签名,你当前的getwss_cb参数和返回值都不符合规范,这会让libcurl无法正确处理后续逻辑,直接终止连接。 - 回调未返回正确字节数:libcurl通过回调的返回值判断传输是否正常,如果返回0或错误值,它会认为出了问题,主动断开连接。
修正后的完整代码
#include <stdio.h> #include <string.h> #include <curl/curl.h> // 符合libcurl要求的回调函数签名 size_t getwss_cb(char *ptr, size_t size, size_t nmemb, void *userdata) { // 计算实际接收的字节总数 size_t total_bytes = size * nmemb; // 安全打印数据(流式数据不一定带\0终止符,用%.*s避免越界) printf("Received data: %.*s\n", (int)total_bytes, ptr); // 返回处理的字节数,告诉libcurl继续监听流 return total_bytes; } int getwss(void) { CURL *easyhandle = curl_easy_init(); if (!easyhandle) { fprintf(stderr, "初始化curl失败!\n"); return 1; } // 替换为你的Pushbullet Access Token curl_easy_setopt(easyhandle, CURLOPT_URL, "https://stream.pushbullet.com/streaming/<access-token>"); // 设置正确的回调函数 curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, getwss_cb); // 启用TCP保活,防止长期无数据时被防火墙/路由器断开 curl_easy_setopt(easyhandle, CURLOPT_TCP_KEEPALIVE, 1L); curl_easy_setopt(easyhandle, CURLOPT_TCP_KEEPIDLE, 30L); // 30秒后开始发保活包 curl_easy_setopt(easyhandle, CURLOPT_TCP_KEEPINTVL, 10L); // 每10秒发一次保活包 // 允许连接复用,避免每次断开后重新建立连接 curl_easy_setopt(easyhandle, CURLOPT_FORBID_REUSE, 0L); // 执行请求,这个调用会一直阻塞直到连接主动断开或出错 CURLcode res = curl_easy_perform(easyhandle); if (res != CURLE_OK) { fprintf(stderr, "请求失败:%s\n", curl_easy_strerror(res)); } curl_easy_cleanup(easyhandle); return 0; }
关键修改说明
- 回调函数修正:用了libcurl要求的标准签名,返回实际处理的字节数,确保libcurl知道传输正常,继续保持连接。
- TCP保活配置:添加了保活参数,防止长时间无数据时连接被中间网络设备强制断开,这对长连接场景非常重要。
- 错误检查:增加了curl初始化的错误判断,避免空指针导致的崩溃。
- 安全打印:用
%.*s格式化输出,避免流式数据无终止符时的printf越界问题。
额外提示
- 记得把代码里的
<access-token>替换成你自己的Pushbullet有效令牌。 - 如果需要优雅终止程序(比如按Ctrl+C),可以添加信号处理逻辑,调用
curl_easy_cleanup来关闭连接。 curl_easy_perform会一直阻塞运行,直到连接断开或出现错误,这正是你需要的“持续监听”效果。
内容的提问来源于stack exchange,提问作者Rumesh
相关产品推荐
相关产品推荐

