android - 使用 CURL 从网页获得大量响应后,缓冲区被截断

标签 android c curl libcurl

我正在使用 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   .............

Note: this is a custom android log. please don't confuse with the output lines

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

当我给curl命令行选项时

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

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

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

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

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);
            }
        }
    }
} 

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

最佳答案

您分配 buffer 的大小为 memorysize(19189 字节)。

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

也许你应该摆脱所有与 buffer 相关的代码并用类似的东西退出你的函数:

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

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

一些其他评论:

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

关于android - 使用 CURL 从网页获得大量响应后,缓冲区被截断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19922849/

相关文章:

java - 从插件中扩展 Activity 的类获取值

c - 双指针的定义

web-services - 如何使用命令行 curl 测试 Web 服务

C++ – cURL cmd, stderr 管道传输到程序,非常慢

android - 在 Android App UI 中实现 "Drilldown"导航

javascript - 如何使用 React Native 制作启动画面

android - onRetainCustomNonConfigurationInstance 什么时候被调用?在设备端更改语言环境期间是否会调用它?

c++ - 我无法理解 C++ 中的结构声明

c - ARM 上的 double2unsigned(vcvt 指令)

javascript - BodyParser 行为