que - Cómo reanudar la descarga de archivos a través de FTP utilizando Curl en C?
que significa el comando curl (2)
Agregue una estructura de ftpfile válida para conocer su función de escritura de la necesidad de abrir y decirle a libcurl que reanude la descarga desde el final del archivo de destino configurando CURLOPT_RESUME_FROM en la cantidad de bytes descargados:
struct FtpFile
{
const char *pcInfFil;
FILE *pFd;
int iAppend;
};
En principal, si quieres reanudar:
curl_easy_setopt(curl, CURLOPT_RESUME_FROM , numberOfBytesToSkip);
Si el archivo aún no existe, o no se trata de una descarga reanudada sino de una nueva descarga, asegúrese de restablecer el CURLOPT_RESUME_FROM a 0.
En my_fwrite:
out->stream=fopen(out->filename, out->iAppend ? "ab":"wb");
PD: si necesita reanudar el archivo es más largo que un largo (2 GB), busque en CURLOPT_RESUME_FROM_LARGE y CURL_OFF_T_C ()
En respuesta a un comentario que solicita información adicional sobre cómo saber cuándo falló una transferencia:
Después de llamar a curl, realice una llamada fácil:
CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ... );
Recuperar del contexto curl:
CURLINFO_HEADER_SIZE
CURLINFO_CONTENT_LENGTH_DOWNLOAD
Agrégalos juntos y asegúrate de que sean iguales
CURLINFO_SIZE_DOWNLOAD
Si no, intenta volver a interpretar el contexto.
Y asegúrese de usar la última versión de curl, debería transcurrir el tiempo después de 60 segundos de no escuchar desde el servidor FTP desde el que se está descargando.
Estoy tratando de descargar un archivo usando FTP, y en el medio si la conexión termina, entonces debe reanudarse desde donde se detuvo. Mi problema es que al usar el siguiente fragmento de código puedo continuar la descarga si cierro la conexión y luego la conecto nuevamente, pero si lo hago en el sitio del servidor, entonces no puedo reanudar la descarga, y el programa entra en estado infinito.
#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:[email protected]/dev.zip");
/* Define our callback to get called when there''s 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;
}
¿Podría alguien decirme que cómo puedo reanudar la descarga si la conexión está cerrada por un sitio remoto? Cualquier ayuda sería apreciada
Gracias,
Yuvi
Puede usar los parámetros CURLOPT_CONNECTTIMEOUT y CURLOPT_TIMEOUT para especificar un tiempo de espera de conexión y un tiempo máximo de ejecución por manejador.
La otra forma (que solo funciona si está usando la interfaz fácil, no la múltiple) es usar una devolución de llamada con opción de socket, que puede establecer usando CURLOPT_SOCKOPTFUNCTION. En él, debe llamar a setsockopt () para el parámetro SO_RCVTIMEO a la cantidad máxima de tiempo que una conexión puede estar inactiva antes de que se elimine. es decir, si no se han recibido bytes en los últimos 5 segundos, suelte la conexión.