【问题标题】:buffer getting truncated after getting a huge response using CURL, from a webpage使用 CURL 从网页获得巨大响应后,缓冲区被截断
【发布时间】:2013-11-24 05:28:58
【问题描述】:

我正在使用 libcurl 执行 HTTP 请求并响应我的网页。 但是当得到响应时,我没有得到完整的服务器响应。响应线在某一点被截断。例如

10-25 15:53:22.264: XXX(14847): Security.8021x:true
10-25 15:53:22.264: XXX(14847): Event.AlarmInput:true
10-25 15:53:22.264: XXX(14847): Event.AlarmInput.Notification.HTTP.CGI:true
10-25 15:53:22.264: XXX(14847): Event.AlarmInput.Notification.HTTP.CGI.SingleSession:true
10-25 15:53:22.264: XXX(14847): Event.AlarmInpu   .............

注意:这是一个自定义的 android 日志。请不要与输出行混淆

响应中还有大约 10 行,但我当前的日志显示“Event.AlarmInpu”之后没有输出。

当我给出 curl 命令行选项时

curl http://www.google.com > output.txt   

我可以在文件中找到完整的输出行。

当我使用 curl 命令行工具并将响应移动到输出文件时,我可以看到整个响应数据。所以我可以同意 curl 命令正在正确检索整个响应。 我得到了整个响应,但是响应比我的缓冲区长度长,因此它被截断了。

请告诉我如何增加缓冲区长度以获得完整的响应行。
代码sn-p如下所示

typedef struct pageInfo_t {
    char *data;
    int  len;
} pageInfo_t;

static size_t HTTPData(void *buffer, size_t size, size_t nmemb, void *userData)
{
    int len = size * nmemb;
    pageInfo_t *page = (pageInfo_t *)userData;
    page->data = realloc(page->data,page->len + len +1);
    memcpy(&page->data[page->len], buffer, len);
    page->len += len;
    page->data[page->len] = 0;
    return len;
}

//Inteface funciton that will recieve web page fom Java
jstring Java_com_samsung_jnitest_MainActivity_JNIGetWebpage( JNIEnv* env,jobject entryObject,jstring webpageJStr)
{
    pageInfo_t page;
    CURL *curl;
    CURLcode res;
    char *buffer;

    int memorysize = 19189;
    page.data = (char *)malloc(16 * memorysize);
    page.len = 0;

    if (page.data)
        memset(page.data, 32, 16 * memorysize);

    buffer = (char *)malloc(memorysize);

    curl = curl_easy_init();
    if(curl)
    {
        curl_easy_setopt(curl, CURLOPT_URL, webpage);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HTTPData);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &page);
        res = curl_easy_perform(curl);
        curl_easy_cleanup(curl);
        (*env)->ReleaseStringUTFChars(env, webpageJStr, webpage);
        if(response_code == 200) 
        {
            if (buffer) 
            {
                page.data[page.len] = '\0';
                sprintf(buffer, "%ld:%s \n", response_code, page.data);
                return (*env)->NewStringUTF(env, buffer);
            }
        }
    }
} 

请告诉我如何增加缓冲区大小以容纳完整的响应行。
如果我的代码过于复杂,请告诉我

【问题讨论】:

    标签: android c curl libcurl


    【解决方案1】:

    您分配buffer 的大小为memorysize19189 字节)。

    但是,page.data 指向的缓冲区会根据 HTTP 请求返回的数据量而增长。但是,无论buffer 是否足够大,都将page.data 指向的空终止字符串复制到buffer

    也许您应该摆脱与buffer 相关的所有代码并使用以下内容退出您的函数:

    jstring retval = (*env)->NewStringUTF(env, page.data);
    free(page.data);
    return retval;
    

    response_code != 200的情况不要忘记正确清理。

    其他几个cmets:

    • 我看不到 webpage 是如何设置或声明的 - 我假设在您的真实代码中有对 GetStringUTFChars() 的省略调用?
    • 我不熟悉 JNI,因此我可能无法正确处理上述建议中的 jstring 结果。
    • 我很好奇 - 当您使用 curl 命令行工具将 HTTP 响应放入一个文件时,该文件最终有多大?

    【讨论】:

    • 我尝试只返回“page.data”,但它仍然包含与之前相同的输出行,当我使用“buffer”时。
    • 当我尝试一个简单的程序(基于 libcurls 的 simple.c 示例)时,它与你的基本相同,但去掉了 JNI 内容,我在page.data 中得到了预期的数据。也许你可以在你的问题 URL 上自己尝试一下:gist.github.com/anonymous/7441125
    • 我按照您的示例进行操作..但我无法在 page.data 中获得完整的响应我正在使用安装在 apache 服务器内的 sample.pl 文件进行测试。我尝试向该脚本发送请求并使用 curl 获取响应。我将添加我的 perl 脚本代码。您可以尝试安装 apache 服务器并将这些行添加到 sample.pl 文件中吗?然后使用浏览器检查它是否在您访问时打印输出。如果一切都完成了......那么你可以尝试使用 curl 程序来获取并打印输出吗?如果成功请告诉我。
    • #!"D:\xampp\perl\bin\perl.exe" ## ## printenv -- 仅打印其环境的演示 CGI 程序 ## print "Content-type: text/plain ; 字符集=utf-8\n\n"; foreach $var (sort(keys(%ENV))) { $val = $ENV{$var}; $val =~ s|\n|\\n|g; $val =~ s|"|\\"|g;打印 "${var}=\"${val}\"\n";这是程序。只需将其复制到记事本中并保存为 .pl 文件即可。请多次添加 foreach 循环以使响应输出更大。然后使用当前的 libcurls sample.c 示例进行测试
    • 我需要延迟一些吗,因为我在我的应用程序中尝试了 simple.c 代码。但我仍然只得到我回复的第一部分。获得完整响应是否有任何延迟.. 我尝试在 size_t 方法中添加 printf 语句,发现 len 变量正在打印 3 次..我知道该方法被多次调用,直到写入完整的数据块
    【解决方案2】:

    我遇到了同样的问题,通过扩展 CURLOPT_TIMEOUT_MS 为我解决了这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-17
      • 1970-01-01
      • 2018-12-29
      • 1970-01-01
      • 2010-11-03
      • 2014-05-15
      • 1970-01-01
      相关资源
      最近更新 更多