libcurl从HTTP请求中检索响应

libcurl从HTTP请求中检索响应,c,http-post,libcurl,C,Http Post,Libcurl,在我的OSX应用程序中,我使用NSURLRequest向服务器发送HTTP请求并接收响应已经有一段时间了。 现在我需要将这段代码迁移到使用libcurl,以便能够在Windows和Mac上运行它 由于某种原因,我不能让它工作 以下是我想做的: 使用HTTP post向服务器发送块 服务器评估块并将响应发送回 接收响应、评估、继续 当随请求一起发送的数据块有效时,“应用程序/八位字节流”数据块将立即发送回请求应用程序。如果文件无效,则返回返回代码403 当我尝试将post请求URL和数据块直接

在我的OSX应用程序中,我使用NSURLRequest向服务器发送HTTP请求并接收响应已经有一段时间了。 现在我需要将这段代码迁移到使用libcurl,以便能够在Windows和Mac上运行它

由于某种原因,我不能让它工作

以下是我想做的:

  • 使用HTTP post向服务器发送块
  • 服务器评估块并将响应发送回
  • 接收响应、评估、继续
当随请求一起发送的数据块有效时,“应用程序/八位字节流”数据块将立即发送回请求应用程序。如果文件无效,则返回返回代码403

当我尝试将post请求URL和数据块直接放在浏览器中时,它会起作用。 如果数据块有效,将下载文件,如果无效,将显示403页

我的libcurl代码如下所示:

curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();

if (curl)
{
    struct url_data data;
    data.size = 0;
    data.data = (char*) malloc(4096); /* reasonable size initial buffer */

    if(NULL == data.data)
    {
        fprintf(stderr, "Failed to allocate memory.\n");
        return NULL;
    }

    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    curl_easy_setopt(curl, CURLOPT_URL, "<my-url>");
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, [postData cStringUsingEncoding:NSASCIIStringEncoding]);

    curl_slist_append(headerlist, "Content-Type: application/x-www-form-urlencoded");
    curl_slist_append(headerlist, [length cStringUsingEncoding:NSASCIIStringEncoding]);

    curl_easy_setopt(curl, CURLOPT_HEADER, headerlist);

    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data);

    curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");

    res = curl_easy_perform(curl);

    if(res != CURLE_OK)
    {
        fprintf(stderr, "curl_easy_perform() failed: %s\n",
                         curl_easy_strerror(res));
    }

    curl_easy_cleanup(curl);
    }
    curl_global_cleanup();
}
struct url_data 
{
    size_t size;
    char* data;
};

size_t write_data(void *ptr, size_t size, size_t nmemb, struct url_data *data)
{
    size_t index = data->size;
    size_t n = (size * nmemb);
    char* tmp;

    data->size += (size * nmemb);

    fprintf(stderr, "data at %p size=%ld nmemb=%ld\n", ptr, size, nmemb);
    tmp = (char*) realloc(data->data, data->size + 1); /* +1 for '\0' */

    memcpy((data->data + index), ptr, n);
    data->data[data->size] = '\0';

    return size * nmemb;
}
我收到了正确的返回码和403页,以防块无效。如果它有效,我不会收到响应块。从未调用write函数。连接总是立即关闭

谁能告诉我我做错了什么

以下是libcurl日志输出的一部分:

* Adding handle: conn: 0x2a9ee00
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x2a9ee00) send_pipe: 1, recv_pipe: 0
* About to connect() to <my-url> port 80 (#0)
*   Trying <my-url-ip>...
* Connected to <my-url> (<my-url-ip>) port 80 (#0)
*添加句柄:conn:0x2a9ee00
*正在添加句柄:发送:0
*正在添加句柄:recv:0
*卷曲度加把手尺寸线:长度:1
*-Conn 0(0x2a9ee00)发送管道:1,接收管道:0
*即将将()连接到端口80(#0)
*努力。。。
*已连接到()端口80(#0)
这个回收管可能会导致问题吗? 应该是1吗


我很想听听你的想法!提前谢谢

您应该使用
curl\u easy\u setopt(curl,CURLOPT\u HTTPHEADER,headerlist)传递自定义标题不使用它需要一个long-as参数(0或1不包括/包括正文输出中的标题)。

我发现的唯一问题是您没有从
realloc()
保存新地址。它肯定会崩溃,但是
write_data()
应该至少被调用一次

你怎么知道从来没有人打过电话

请改为尝试此
write_data()

size_t write_data(void *ptr, size_t size, size_t nmemb, struct url_data *data)
{ 
    size_t index = data->size;
    size_t n = (size * nmemb);
    char* tmp;

    data->size += (size * nmemb);

    fprintf(stderr, "data at %p size=%ld nmemb=%ld\n", ptr, size, nmemb);
    tmp = (char*) realloc(data->data, data->size + 1); /* +1 for '\0' */
    if (tmp == NULL) {
        fputs("Error (re)allocating memory", stderr);
        return 0;
    }
    data->data = tmp;

    memcpy((data->data + index), ptr, n);
    data->data[data->size] = '\0';

    return size * nmemb;
}

请显示您的写入函数。@jaeheung更新了问题,谢谢。我没有真正处理写入数据函数,因为它甚至没有被调用。我怀疑这就是错误所在。我认为服务器的响应时间太长,同时连接被关闭。@guitarflow您可以尝试设置CURLOPT_TIMEOUT,但是libcurl手册说“默认超时为0(零),这意味着它永远不会超时。”