libcurl报错Send failed since rewinding of the data stream failed
一、问题描述
- 使用libcurl库发送POST请求,数据格式为 multipart/form-data ,未上传文件。调用
curl_easy_perform成功后未释放内存,又再次调用curl_easy_perform,报错Send failed since rewinding of the data stream failed。

传入的数据源都是字符串,不涉及到文件、缓冲区之类的,很奇怪为什么发送的数据流没有办法被rewind。一开始以为是curl_easy_perform函数的问题,后续逐步测试定位到和curl_mime有关...
直接用的curl库,调试可设置curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);打印详细日志。
二、解决方案
-
- 如果代码涉及到了文件传输,需手动实现数据流回滚,调用
rewind或fseek函数,传入文件指针。
- 如果代码涉及到了文件传输,需手动实现数据流回滚,调用
-
- 如果是自定义的读取函数 (
CURLOPT_READFUNCTION),也要手动考虑数据流回滚,可通过设置CURLOPT_SEEKFUNCTION实现具体操作。
- 如果是自定义的读取函数 (
-
- 检查数据完整性,数据有可能被意外修改或不完整 (
我遇到的情况)
多了一句代码:part_ = curl_mime_addpart(mime);,后续没有跟curl_mime_name和curl_mime_data;或者说连续调用了两次curl_mime_addpart造成数据流无法被rewind。
- 检查数据完整性,数据有可能被意外修改或不完整 (
以下是可稳定复现问题的代码:
cpp
#include "include/curl/curl.h"
#include "iostream"
int main(int argc, char *argv[])
{
CURL *curl;
CURLcode res;
std::string data;
curl = curl_easy_init();
curl_mime *mime;
mime = curl_mime_init(curl);
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:4523/m1/6845287-6559514-default/cs");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Content-Type: multipart/form-data");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
// ------------------------------------
curl_mimepart *part_;
part_ = curl_mime_addpart(mime); // 引起异常的代码
// 测试代码
part_ = curl_mime_addpart(mime);
curl_mime_name(part_,"11");
curl_mime_data(part_, "11", CURL_ZERO_TERMINATED);
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
// ------------------------------------
res = curl_easy_perform(curl);
std::cout << curl_easy_strerror(res) << std::endl;
res = curl_easy_perform(curl);
std::cout << curl_easy_strerror(res) << std::endl;
curl_mime_free(mime);
curl_easy_cleanup(curl);
}
三、参考链接
- 调用libcurl库的curl_easy_perform函数后,程序崩溃:https://blog.csdn.net/Pz_z1/article/details/138536356
- 函数curl_easy_perform在release下崩溃的问题:https://www.cnblogs.com/jackieron/p/6233949.html
- curl_easy_perform()返回值说明:https://blog.csdn.net/weixin_30449453/article/details/96191349
- 详解libcurl Easy interface API(C++):https://zhuanlan.zhihu.com/p/646640511