How to resume file download via FTP using Curl in C?

I am trying to upload a file using FTP, and between them, if the connection ends, it should resume from where it was stopped. My problem is that using the following snippet of code, I can continue downloading if I close the connection and then reconnect it, but if I do this on the server, I can not resume the download, and the program goes to infinite state .

#include <stdio.h> #include <curl/curl.h> /* * This is an example showing how to get a single file from an FTP server. * It delays the actual destination file creation until the first write * callback so that it won't create an empty file in case the remote file * doesn't exist or something else fails. */ struct FtpFile { const char *filename; FILE *stream; }; static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream) { struct FtpFile *out=(struct FtpFile *)stream; if(out && !out->stream) { /* open file for writing */ out->stream=fopen(out->filename, "wb"); if(!out->stream) return -1; /* failure, can't open file to write */ } return fwrite(buffer, size, nmemb, out->stream); } int main(void) { CURL *curl; CURLcode res; struct FtpFile ftpfile={ "dev.zip", /* name to store the file as if succesful */ NULL }; curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); if(curl) { /* * You better replace the URL with one that works! */ curl_easy_setopt(curl, CURLOPT_URL, "ftp://root:password@192.168.10.1/dev.zip"); /* Define our callback to get called when there data to be written */ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite); /* Set a pointer to our struct to pass to the callback */ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile); /* Switch on full protocol/debug output */ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); res = curl_easy_perform(curl); /* always cleanup */ curl_easy_cleanup(curl); if(CURLE_OK != res) { /* we failed */ fprintf(stderr, "curl told us %d\n", res); } } if(ftpfile.stream) fclose(ftpfile.stream); /* close the local file */ curl_global_cleanup(); return 0; } 

Can someone tell me how can I resume downloading if the connection is closed by the remote site. Any help would be appreciated

Thanks,

Yuvi

+8
c curl libcurl ftp resume
source share
2 answers

Add varaible to the ftpfile structure to learn about your write function, to call and tell libcurl to resume loading from the end of the target file, setting CURLOPT_RESUME_FROM to the number of bytes already loaded:

  struct FtpFile { const char *pcInfFil; FILE *pFd; int iAppend; }; 

Basically, if you want to resume:

 curl_easy_setopt(curl, CURLOPT_RESUME_FROM , numberOfBytesToSkip); 

If you do not exist yet, or it is not a resumed download, but a new download, be sure to return CURLOPT_RESUME_FROM to 0.

In my_fwrite:

 out->stream=fopen(out->filename, out->iAppend ? "ab":"wb"); 

PS if you need to renew a file larger than a long (2 GB), check out CURLOPT_RESUME_FROM_LARGE and CURL_OFF_T_C ()

In response to a comment requesting additional information on how to find out when a transmission failure:

After you call curl easy, call:

 CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ... ); 

Get out of curl context:

 CURLINFO_HEADER_SIZE CURLINFO_CONTENT_LENGTH_DOWNLOAD 

Add them together and make sure they are equal.

 CURLINFO_SIZE_DOWNLOAD 

If you do not try to change the context.

And do not forget to use the latest version of curl, it should expire 60 seconds after you do not hear from the FTP server from which it is downloaded.

+2
source share

You can use the CURLOPT_CONNECTTIMEOUT and CURLOPT_TIMEOUT parameters to specify the connection timeout and maximum execution time for each control.

Another way (works only if you use a simple interface, not a multi-one) is to use the socket option callback, which you can set using CURLOPT_SOCKOPTFUNCTION. In it, you must call setsockopt () on the SO_RCVTIMEO parameter until the maximum time that the connection can be idle before it is deleted. those. if no bytes have been received in the last 5 seconds, then drop the connection.

0
source share

All Articles