【问题标题】:libcurl HTTPS POST data send?libcurl HTTPS POST数据发送?
【发布时间】:2011-10-21 14:17:01
【问题描述】:

我的应用程序通过 HTTP POST 请求接收数据。我正在尝试使用 libcurl 打开对该应用程序的请求,发送数据并从应用程序接收回复。这是我到目前为止的代码:

int main(void)
{
    CURL *curl;
    CURLcode res;

    curl = curl_easy_init();
    if(curl) 
    {
        const int timeout = 30000;
        char outputmessage[]="VGhpcyBpcyBqdXN0IGEgbWVzc2FnZSwgaXQncyBub3QgdGhlIHJlYWwgdGhpbmc=";

        curl_easy_setopt(curl, CURLOPT_URL, "https://somehost.com/someapp");
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
        curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.5");
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, outputmessage);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(outputmessage));
        curl_easy_setopt(curl, CURLOPT_POST, 1L);
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout/1000);

        res = curl_easy_perform(curl);
        if(CURLE_OK != res)
        {
            printf("Error: %s\n", strerror(res));
            return 1;
        }

        // now what?

        // cleanup when done
        curl_easy_cleanup(curl);
    }
    return 0;
}

这实际上连接到服务器,我在curl_easy_perform() 上得到了一个确定。我可以在 Wireshark 上看到连接。

两个问题:

1) 这是通过 POST 发送数据的正确方式吗,以及
2) 如何获得应用程序的回复。

我认为我需要使用curl_easy_recv(),但我不知道如何使用。欢迎任何示例代码。 谢谢。

【问题讨论】:

    标签: c libcurl


    【解决方案1】:

    我认为您还应该考虑为响应标头添加处理程序:

    cres = curl_easy_setopt( handle, CURLOPT_HEADERFUNCTION, HandleHeader );
    

    如果这是一个专为应用程序使用而设计的 Web 服务,它的回复可能是一个只有标题的回复,没有响应数据。标头将包含以下数据:

    HTTP/1.1 200 OK ...
    

    您要查找的主要内容是表明请求正常的 200 代码。

    处理来自标头或响应的数据的函数应采用 void*,如果您将其用作字符串,则需要以空值终止它。有关信息,这是我处理传入数据的方式(在这种情况下,我只在我的应用程序中使用返回码 - 响应正文只是转到日志文件):

    static size_t CurlHandleResponse(
      void *Ptr,
      size_t Size,
      size_t NoElements,
      void* Data )
    {
      memcpy( &( gData[gDataLen] ), Ptr, (Size * NoElements) );
      gDataLen += (Size * NoElements);
      gData[ gDataLen ] = '\0';
      return (Size * NoElements);
    }
    
    ...
    ConvertUnprintable( gData, PrintStr );
    ...
    

    为简洁起见删除了错误处理!

    【讨论】:

    • 应用返回的数据正好在200 OK之后。我需要阅读标头以查看请求是否正常,然后是之后的数据。有任何想法吗?而不是归档,而是一个 char*
    • 对于信息,它应该是一个 void *ptr,而不是一个 char *ptr,但我将使用我用来处理响应的代码来编辑我的答案。
    • 知道了,谢谢。现在我需要开始解析所有信息。感谢您的帮助
    【解决方案2】:

    您不需要调用任何接收函数。当控制传递给 write-finished 回调时,收到的响应会返回给您。像这样设置回调:

    curl_res = curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, RecvResponseCallback);

    在调用 perform 之前。

    这样定义回调:

    size_t
    RecvResponseCallback ( char *ptr, size_t size, size_t nmemb, char *data ) {
      // handle received data
      return size * nmemb;
    }
    

    响应数据由 data arg 指向(不是 ptr arg,这是您需要查看的其他内容当你得到这个工作时)。

    退出RecvResponseCallback时,一定要返回(size_t) size * nmemb

    【讨论】:

    • 任何参数都需要在 RecvResponseCallback() 上声明
    • 设置后我调用 perform 我得到Error: Too many open files in system
    • 您运行的系统是什么?我认为 libcurl 必须为接收套接字打开另一个文件。那么你的程序中打开了多少个文件呢?
    • 知道了。我只需要将返回添加到回调函数。无论如何,什么都不会回来。我可以看到与服务器和应用程序的连接,但没有任何回复
    • 此时最好的办法是注册 libcurl-users 邮件列表并在那里提问:cool.haxx.se/mailman/listinfo/curl-users
    猜你喜欢
    • 1970-01-01
    • 2011-05-13
    • 2015-02-28
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 2013-05-24
    • 1970-01-01
    • 2023-03-25
    相关资源
    最近更新 更多