rapido programa para mas gestores gestor descargas descargar chrome acelerar acelerador http file-io download

http - programa - implementar un administrador de descarga que admita la reanudación



programa para acelerar descargas (7)

Tengo la intención de escribir un pequeño administrador de descargas en C ++ que admita la reanudación (y múltiples conexiones por descarga).

De la información que he reunido hasta ahora, al enviar la solicitud http, necesito agregar un campo de encabezado con una clave de "Rango" y el valor "bytes = startoff-endoff". Luego, el servidor devuelve una respuesta http con los datos entre esos desplazamientos.

Así que más o menos lo que tengo en mente es dividir el archivo en la cantidad de conexiones permitidas por archivo y enviar una solicitud http por parte dividida con el "Rango" apropiado. Entonces, si tengo un archivo de 4mb y 4 conexiones permitidas, dividiría el archivo en 4 y tendré 4 solicitudes http, cada una con el campo "Rango" apropiado. Implementar la función de reanudar implica recordar qué compensaciones ya están descargadas y simplemente no solicitarlas.

  • ¿Es esta la manera correcta de hacer esto?
  • ¿Qué sucede si el servidor web no admite la reanudación? (Supongo que ignorará el "Rango" y solo enviará el archivo completo)
  • Al enviar las solicitudes http, ¿debería especificar en el rango todo el tamaño dividido? O tal vez pedir piezas más pequeñas, digamos 1024k por solicitud?
  • Al leer los datos, ¿debo escribirlos inmediatamente en el archivo o hacer algún tipo de almacenamiento en memoria intermedia? Supongo que puede ser un desperdicio escribir pequeños fragmentos.
  • ¿Debo usar un archivo mapeado de memoria? Si mal no recuerdo, se recomienda leer frecuentemente en lugar de escribir (podría estar equivocado). ¿Es sabio en memoria? ¿Qué sucede si tengo varias descargas simultáneamente?
  • Si no estoy usando un archivo mapeado de memoria, ¿debo abrir el archivo por conexión permitida? O cuando necesite escribir en el archivo, simplemente busque? (Si utilicé un archivo mapeado en memoria esto sería muy fácil, ya que simplemente podría tener varios punteros).

Nota: Probablemente usaré Qt, pero esta es una pregunta general, así que dejé el código fuera de ella.


Además de realizar un seguimiento de cuáles fueron los desplazamientos que marcan el comienzo de los segmentos y la longitud de cada segmento (a menos que desee calcular eso en el currículum, lo que implica ordenar la lista compensada y calcular la distancia entre dos), querrá verificar Rango Aceptar-Rangos de la respuesta HTTP enviada por el servidor para asegurarse de que admite el uso del encabezado Rango. La mejor manera de especificar el rango es "Rango: bytes = START_BYTE-END_BYTE" y el rango que solicita incluye START_BYTE y byte END_BYTE, por lo tanto, consiste en (END_BYTE-START_BYTE) +1 bytes.

Solicitar microchips es algo que desaconsejaría ya que podría estar en la lista negra de una regla de firewall para bloquear la inundación HTTP. En general, te sugiero que no hagas trozos de menos de 1MB y no hagas más de 10 trozos. Dependiendo del control que planee tener en su descarga, si tiene control de nivel de socket puede considerar escribir solo una vez cada 32K como mínimo, o escribir datos de manera asincrónica.

No pude comentar la idea de MMF, pero si el archivo descargado es grande, no será una buena idea, ya que comerá mucha RAM e incluso eventualmente hará que el sistema cambie, lo que no es eficiente.

Acerca del manejo de los fragmentos, puede crear varios archivos, uno por segmento, opcionalmente preasignar el espacio en el disco que llena el archivo con tantos / x00 como el tamaño del fragmento (la asignación previa puede ahorrarle algún tiempo mientras escribe durante la descarga, pero hará que comenzar la descarga sea más lento), y finalmente solo escriba todos los fragmentos secuencialmente en el archivo final.

Una cosa que debes tener en cuenta es que varios servidores tienen un máximo. el límite de conexiones simultáneas no lo conoce con anticipación, por lo que debe estar preparado para manejar los errores / tiempos de espera HTTP y para cambiar el tamaño de los fragmentos o crear una cola de los fragmentos en caso de que haya creado más fragmentos que max. conexiones.


En cuanto a la solicitud / respuesta:

para una solicitud Range-d, puede obtener tres respuestas diferentes:

206 Partial Content : reanudación compatible y posible; compruebe el encabezado Content-Range para el tamaño / rango de respuesta
200 OK - los rangos de bytes ("reanudación") no son compatibles, el recurso completo ("archivo") sigue
416 Requested Range Not Satisfiable : rango incorrecto (EOF anterior, etc.)

Content-Range usu. se ve así: Content-Range: bytes 21010-47000/47022 , es decir, bytes de inicio / final.

Compruebe la especificación de HTTP para más detalles, esp. Secciones 14.5, 14.16 y 14.35


Me parece que le gustaría limitar el tamaño por porción de descarga. Trozos grandes podrían forzarlo a repetir la descarga de datos si la conexión se cancela cerca del final de la parte de datos. Especialmente un problema con conexiones más lentas.


No es realmente una respuesta a las preguntas originales, pero otra cosa que vale la pena mencionar es que un programa de descarga reanudable también debe verificar la última fecha de modificación en un recurso antes de tratar de tomar el siguiente fragmento de algo que puede haber cambiado.


No puedo responder todas sus preguntas, pero esta es mi opinión sobre dos de ellas.

Tamaño de porción

Hay dos cosas que debes considerar sobre el tamaño del fragmento:

  1. Cuanto más pequeños son, más sobrecarga se obtiene al enviar la solicitud HTTP.
  2. Con trozos más grandes, corre el riesgo de volver a descargar los mismos datos dos veces, si falla una descarga.

Te recomiendo que vayas con pequeños pedazos de datos. Sin embargo, tendrá que hacer algunas pruebas para ver cuál es el mejor para su propósito.

En memoria vs. archivos

Debería escribir los fragmentos de datos en el búfer de la memoria y luego, cuando esté lleno, escribirlo en el disco. Si va a descargar archivos grandes, puede ser problemático para sus usuarios, si se quedan sin memoria RAM. Si recuerdo correctamente que el IIS almacena solicitudes menores de 256 kb en memoria, se escribirá en el disco cualquier cosa más grande, es posible que desee considerar un enfoque similar.


No soy un experto en C ++, sin embargo, una vez hice una aplicación .NET que necesitaba una funcionalidad similar (programación de descargas, soporte de reanudación, priorización de descargas)

utilicé el componente microsoft bits (Servicio de transferencia inteligente en segundo plano), que se desarrolló en c. la actualización de Windows también usa BITS. Fui por esta solución porque no creo ser un programador lo suficientemente bueno como para escribir algo de este nivel ;-)

Aunque no estoy seguro de si puede obtener el código de BITS, creo que debería echarle un vistazo a su documentación que podría ayudarlo a comprender cómo lo implementaron, la arquitectura, las interfaces, etc.

Aquí está - http://msdn.microsoft.com/en-us/library/aa362708(VS.85).aspx