cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: Wrong behavior when activate the LOW_SPEED_LIMIT and LOW_SPEED_TIME

From: Jie He <jie.he.cn_at_gmail.com>
Date: Mon, 24 Sep 2012 11:31:07 +0800

// TestMulti.cpp : Defines the entry point for the console application.
//

#include "curl/curl.h"

int total_length = 0;
size_t func_writer(char *ptr, size_t size,
        size_t nmemb, void *userdata)
{
    FILE* file_write = (FILE*)userdata;
    size_t write_count = 0;
    write_count = fwrite(ptr, size, nmemb, file_write);

    total_length += write_count;

    char buf[50] = "";
    sprintf(buf, "complete length = %d\n", total_length);
    printf(buf);
    return write_count;
};

int main(int argc, char* argv[])
{
    CURLM* handle_multi = NULL;
    CURL* handle_curl = NULL;
    FILE* file_write = NULL;

    total_length = 0;
    file_write = fopen("c:/temp/testfile", "wb+");
    if (!file_write)
        return -1;

    curl_global_init(CURL_GLOBAL_ALL);

    handle_curl = curl_easy_init();
    handle_multi = curl_multi_init();

    curl_easy_setopt(handle_curl, CURLOPT_USERAGENT,
            "Mozilla/5.0 (Windows; U; Windows NT 5.1; \
    en-US; rv:1.8.1.1) \
    Gecko/20061204 Firefox/2.0.0.1");

   curl_easy_setopt(handle_curl, CURLOPT_URL,
            "http://www.kuaizip.com/down/Kuaizip_Setup_v2.6.21.0B.exe");
    curl_easy_setopt(handle_curl, CURLOPT_MAX_RECV_SPEED_LARGE, 1024);
    curl_easy_setopt(handle_curl, CURLOPT_FOLLOWLOCATION, 1L);
    curl_easy_setopt(handle_curl, CURLOPT_LOW_SPEED_LIMIT, 1);
    curl_easy_setopt(handle_curl, CURLOPT_LOW_SPEED_TIME, 60);
    // save the received data to file
    curl_easy_setopt(handle_curl, CURLOPT_WRITEFUNCTION, func_writer);
    curl_easy_setopt(handle_curl, CURLOPT_WRITEDATA, file_write);

    curl_multi_add_handle(handle_multi, handle_curl);

    int running_handles = 0;

    do {
        struct timeval timeout;
        int rc = 0; /* select() return code */
        CURLMcode ret = CURLM_OK;

        fd_set fdread;
        fd_set fdwrite;
        fd_set fdexcep;

        FD_ZERO(&fdread);
        FD_ZERO(&fdwrite);
        FD_ZERO(&fdexcep);

        int maxfd = -1;
        long curl_timeo = -1;

        /* set a suitable timeout to play around with */
        timeout.tv_sec = 1;
        timeout.tv_usec = 0;

        curl_multi_timeout(handle_multi, &curl_timeo);

        if(curl_timeo >= 0) {
            timeout.tv_sec = curl_timeo / 1000;
            if(timeout.tv_sec > 1)
                timeout.tv_sec = 1;
            else
                timeout.tv_usec = (curl_timeo % 1000) * 1000;
        }

        /* get file descriptors from the transfers */
        curl_multi_fdset(handle_multi, &fdread, &fdwrite, &fdexcep, &maxfd);

        /* In a real-world program you OF COURSE check the return code of
the
        function calls. On success, the value of maxfd is guaranteed to be
        greater or equal than -1. We call select(maxfd + 1, ...),
specially in
        case of (maxfd == -1), we call select(0, ...), which is basically
equal
        to sleep. */
        if (maxfd == -1) {

            Sleep(100);

        } else {
            rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);

            switch(rc) {
            case -1:
                return -1;
            case 0: /* timeout */
            default: /* action */
                break;
            }
        }

        // change the running_handles's value, thus, lock this function
        curl_multi_perform(handle_multi, &running_handles);

    } while (running_handles);

    /* check which transfer has be done.*/
    CURLMsg *msg = NULL; /* for picking up messages with the transfer
status */
    int msgs_left = 0; /* how many messages are left */
    /* See how the transfers went */
    while ((msg = curl_multi_info_read(handle_multi, &msgs_left))) {

        if (msg->msg == CURLMSG_DONE) {
            if (msg->data.result == CURLE_OPERATION_TIMEDOUT)
                printf("operation timeout trigged\n");
            break;
        }
    }

    curl_multi_remove_handle(handle_multi, handle_curl);
    curl_easy_cleanup(handle_curl);
    curl_multi_cleanup(handle_multi);
    curl_global_cleanup();

    fclose(file_write);

return 0;
}

I wrote the above code, and test it on Windows 7, reproduce the behavior.

I set the timeout to 60s. and attach the screen snapshot in email.

you can see that the operation timeout occurs in 1 min.

2012/9/23 Daniel Stenberg <daniel_at_haxx.se>

> On Sat, 22 Sep 2012, Jie He wrote:
>
> I forgot, I'm using multi interface to download.
>>
>
> So can you please update my example in a way so that it fails for you and
> post it here?
>
>
> --
>
> / daniel.haxx.se
> ------------------------------**------------------------------**-------
> List admin: http://cool.haxx.se/list/**listinfo/curl-library<http://cool.haxx.se/list/listinfo/curl-library>
> Etiquette: http://curl.haxx.se/mail/**etiquette.html<http://curl.haxx.se/mail/etiquette.html>
>

-- 
Best Regards
He Jie ºÎ½Ü


-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html

test.jpg
Received on 2012-09-24