cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: Questions about timeout during transfer

From: Saqib Ali <saqib.ali.75_at_gmail.com>
Date: Thu, 26 May 2011 10:36:43 -0400

- Saqib

On Thu, May 26, 2011 at 1:47 AM, Saqib Ali <saqib.ali.75_at_gmail.com> wrote:

>
>
> You certainly are not the only one, that's why libcurl provides these
>> options:
>>
>> http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTLOWSPEEDLIMIT
>> http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTLOWSPEEDTIME
>>
>> - Jeff
>>
>
>
> Thanks Jeff! This was very helpful.
>
> The Low-Speed timeout works pretty well for me.
> However, I ran some tests that raise questions in my mind about certain
> delays that I'm noticing..
>
> I set my low-speed limit to 1 byte/sec. And I set the low-speed time to 1
> second.
> I start a transfer. During the transfer I break the connection between the
> two machines. Below I have included the output of the test (with some minor
> annotations in < >) and the source-code of my test program.
>
> Even though I set the low-speed-time to 60 seconds, It waits 68 seconds
> before timing out.
> After it times out, disconnecting and closing the connection takes a
> whopping 62 additional seconds. Why is there an 8-second delay on my timer.
> And why does it take 62 seconds to disconnect? Is that normal?
>
> - Saqib
>
> Standard Output:
> =============
> % myProg
> Enter File Name: myFile.dat
> * About to connect() to myIPAddr port 22 (#0)
> * Trying myIPAddr... * 0x67e18 is at send pipe head!
> * STATE: CONNECT => WAITCONNECT handle 0x49c78; (connection #0)
> * Connected to myIPAddr (myIPAddr) port 22 (#0)
> * SFTP 0x70b38 state change from SSH_STOP to SSH_S_STARTUP
> * SFTP 0x70b38 state change from SSH_S_STARTUP to SSH_HOSTKEY
> * SFTP 0x70b38 state change from SSH_HOSTKEY to SSH_AUTHLIST
> * STATE: WAITCONNECT => PROTOCONNECT handle 0x49c78; (connection #0)
> * SSH authentication methods available:
> gssapi-keyex,gssapi-with-mic,publickey,password,keyboard-interactive
> * SFTP 0x70b38 state change from SSH_AUTHLIST to SSH_AUTH_PKEY_INIT
> * Using ssh public key file /myHomeDir/.ssh/id_dsa.pub
> * Using ssh private key file /myHomeDir/.ssh/id_dsa
> * SFTP 0x70b38 state change from SSH_AUTH_PKEY_INIT to SSH_AUTH_PKEY
> * SSH public key authentication failed: Unable to open public key file
> * SFTP 0x70b38 state change from SSH_AUTH_PKEY to SSH_AUTH_PASS_INIT
> * SFTP 0x70b38 state change from SSH_AUTH_PASS_INIT to SSH_AUTH_PASS
> * Initialized password authentication
> * SFTP 0x70b38 state change from SSH_AUTH_PASS to SSH_AUTH_DONE
> * Authentication complete
> * SFTP 0x70b38 state change from SSH_AUTH_DONE to SSH_SFTP_INIT
> * SFTP 0x70b38 state change from SSH_SFTP_INIT to SSH_SFTP_REALPATH
> * SSH CONNECT phase done
> * SFTP 0x70b38 state change from SSH_SFTP_REALPATH to SSH_STOP
> * STATE: PROTOCONNECT => DO handle 0x49c78; (connection #0)
> * DO phase starts
> * SFTP 0x70b38 state change from SSH_STOP to SSH_SFTP_QUOTE_INIT
> * SFTP 0x70b38 state change from SSH_SFTP_QUOTE_INIT to SSH_SFTP_TRANS_INIT
> * SFTP 0x70b38 state change from SSH_SFTP_TRANS_INIT to
> SSH_SFTP_UPLOAD_INIT
> * STATE: DO => DOING handle 0x49c78; (connection #0)
> * SFTP 0x70b38 state change from SSH_SFTP_UPLOAD_INIT to SSH_STOP
> * DO phase is complete
> * STATE: DOING => DO_DONE handle 0x49c78; (connection #0)
> 11 | 0% transferred.
> * STATE: DO_DONE => WAITPERFORM handle 0x49c78; (connection #0)
> * STATE: WAITPERFORM => PERFORM handle 0x49c78; (connection #0)
> * Expire cleared
> Elapsed Time: 11 seconds | 3.11223% transferred.
> Elapsed Time: 12 seconds | 6.22445% transferred.
> Elapsed Time: 12 seconds | 9.33668% transferred.
> Elapsed Time: 12 seconds | 12.4489% transferred.
> Elapsed Time: 12 seconds | 15.5611% transferred.
> Elapsed Time: 13 seconds | 18.6734% transferred.
> Elapsed Time: 13 seconds | 21.7856% transferred.
> Elapsed Time: 13 seconds | 24.8978% transferred.
> Elapsed Time: 14 seconds | 28.01% transferred.
> Elapsed Time: 14 seconds | 31.1223% transferred.
> Elapsed Time: 14 seconds | 34.2345% transferred.
> Elapsed Time: 15 seconds | 37.3467% transferred.
> Elapsed Time: 15 seconds | 40.4589% transferred.
> Elapsed Time: 15 seconds | 43.5712% transferred.
> Elapsed Time: 16 seconds | 46.6834% transferred.
> Elapsed Time: 16 seconds | 49.7956% transferred.
> Elapsed Time: 16 seconds | 52.9078% transferred.
> Elapsed Time: 17 seconds | 56.0201% transferred.
> Elapsed Time: 17 seconds | 59.1323% transferred.
> Elapsed Time: 17 seconds | 62.2445% transferred.
> Elapsed Time: 18 seconds | 65.3567% transferred.
> Elapsed Time: 18 seconds | 68.469% transferred.
> Elapsed Time: 19 seconds | 71.5812% transferred.
> Elapsed Time: 19 seconds | 74.6934% transferred.
> Elapsed Time: 19 seconds | 77.8056% transferred.
> Elapsed Time: 20 seconds | 80.9179% transferred.
> Elapsed Time: 20 seconds | 84.0301% transferred.
>
> <Annotation: The connection is broken at this point....Wait of 68
> seconds...>
>
> * Operation too slow. Less than 1 bytes/sec transfered the last 60 seconds
> * SSH DISCONNECT starts now
> * SFTP 0x70b38 state change from SSH_STOP to SSH_SFTP_SHUTDOWN
>
> <Annotation: Wait of 62 seconds>
>
> * Operation too slow. Less than 1 bytes/sec transfered the last 60 seconds
> * SSH DISCONNECT is done
> * Closing connection #0
> Elapsed Time: 150 seconds | Xfer Stopped! stillRunning = 0
> * Expire cleared
> curl_multi_remove_handle() was successfull!
>
>
> My Test Program So that you can reproduce:
> ==================================
>
> #include "curl.h"
> #include <iostream>
> #include <unistd.h>
> #include <sys/stat.h>
> #include <time.h>
>
> using namespace std;
>
>
> typedef int (*callBackP) (void *clientp, double dltotal, double dlnow,
> double ultotal, double ulnow);
> time_t startTime = time(0);
>
>
> static int progressCallBack(void *argSrcFile, double dltotal, double dlnow,
> double ultotal, double ulnow)
> {
>
> static double lastPrint;
>
>
> if (ultotal > 0)
> {
> double currProg = (ulnow*100)/ultotal;
> if ((currProg >= (lastPrint+3.0) || currProg >= 100))
> {
> lastPrint = currProg;
> cout << "Elapsed Time: " << difftime(time(0), startTime) << "seconds | "
> << currProg << "% transferred." << endl;
> }
> if (currProg == 100)
> {
> lastPrint = -5.0;
> return -1;
> }
> }
> else
> {
> lastPrint = -5.0;
> }
> return 0;
> }
>
>
>
>
> int main()
> {
> CURLMcode retVal;
>
> curl_global_init(CURL_GLOBAL_ALL);
> CURLM* multiHandle = curl_multi_init();
> CURL* newEasyHandle = curl_easy_init();
>
> string fileName;
> cout << "Enter File Name: ";
> cin >> fileName;
>
> string targetURL = "sftp://myIPAddr/~/" + fileName;
>
> curl_easy_setopt(newEasyHandle, CURLOPT_UPLOAD, 1);
> curl_easy_setopt(newEasyHandle, CURLOPT_VERBOSE, 1);
> curl_easy_setopt(newEasyHandle, CURLOPT_CONNECTTIMEOUT, 60);
> curl_easy_setopt(newEasyHandle, CURLOPT_LOW_SPEED_LIMIT, 1);
> curl_easy_setopt(newEasyHandle, CURLOPT_LOW_SPEED_TIME, 60);
>
> // Setup The Callback function
> callBackP currCallBack = progressCallBack;
> curl_easy_setopt(newEasyHandle, CURLOPT_NOPROGRESS, 0);
> curl_easy_setopt(newEasyHandle, CURLOPT_PROGRESSFUNCTION,
> progressCallBack );
> curl_easy_setopt(newEasyHandle, CURLOPT_PROGRESSDATA, (void*)NULL);
>
>
> FILE* fd = fopen(fileName.c_str(), "r"); // open file to upload
> curl_easy_setopt(newEasyHandle, CURLOPT_READDATA, fd);
> curl_easy_setopt(newEasyHandle, CURLOPT_USERPWD,
> "myUserName:myPassword");
> curl_easy_setopt(newEasyHandle, CURLOPT_URL, targetURL.c_str());
> struct stat fileInfo;
> stat(fileName.c_str(), &fileInfo);
> curl_easy_setopt(newEasyHandle, CURLOPT_INFILESIZE,
> (long)fileInfo.st_size);
>
>
> // BLOCK A: Now add the easyHandle to the multiStack
> curl_multi_add_handle(multiHandle, newEasyHandle);
> int stillRunning, retValcm;
> retVal = curl_multi_perform(multiHandle, &stillRunning);
> if (retVal != CURLM_OK)
> cout << "curl_multi_perform() failed!" << endl;
> // END BLOCK A
>
>
>
> // BLOCK B: Wait until the transfers are done.
> while (stillRunning > 0)
> {
> retValcm = curl_multi_perform(multiHandle, &stillRunning);
> }
> // END BLOCK B
> cout << "Elapsed Time: " << difftime(time(0), startTime) << "seconds | " <<
> "Xfer Stopped! stillRunning = " << stillRunning << endl;
>
>
>
> // BLOCK C: Now remove the easyHandle from the multiStack
> sleep(2);
> retVal = curl_multi_remove_handle(multiHandle, newEasyHandle);
> if (retVal == CURLM_OK)
> cout << "curl_multi_remove_handle() was successfull!" << endl;
> else
> cout << "curl_multi_remove_handle() failed!" << endl;
> // END BLOCK C
>
> return 0;
>
> }
>
>
>

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2011-05-26