HTTP Split Download Typ mit Python gemacht

Auslösen

――Ich habe einen Vertrag für die optische Leitung meines Hauses mit 1 Gbit / s abgeschlossen, aber als ich versuchte, eine große Datei (ISO von Linux) usw. über HTTP herunterzuladen, kam die Geschwindigkeit nicht heraus

Warum?

$cat /proc/sys/net/ipv4/tcp_rmem
4096    87380   6291456

Von links [min, default, max]

Der maximale Durchsatz ist also

T_{max} = win / RTT

Wenn es sich also um eine einzelne TCP-Verbindung handelt, erfolgt die Kommunikation mit einem Server mit RTT = 30 ms im Standardzustand ~~ Ungefähr 87380 [Byte] * 8/30 [ms] ≒ 23,3 [Mbit / s] nur ~~ In der Tat, ** wenn es keine Überlastung gibt **, wird die Fenstergröße immer größer, so dass es schneller wird.

Natürlich verfügt TCP über eine Fensterskalierungsoption zur Unterstützung von Breitbandnetzwerken. Die Fenstergröße kann auf 1 GByte erweitert werden (es ist nicht bekannt, ob es tatsächlich verwendet wird).

Wenn es theoretisch mehrere Verbindungen gibt und N Leitungen gebündelt sind, ist das Band N-mal

Bestehende Werkzeuge

Wget und Curl sind als Werkzeuge bekannt, die über die Befehlszeile verwendet werden können Es gibt aria2 usw., die mehrere Verbindungen verwenden können Verwenden Sie den explosiven Downloader aria2, der um ein Vielfaches schneller ist als curl and wget --Qiita Überlasten Sie den anderen Server nicht, wenn Sie mehrere Verbindungen herstellen

Erstellen eines HTTP-Clients für den Betreff

HTTP hat eine Bereichsanforderung RFC 7233 - HTTP / 1.1: Bereichsanforderungen Die Implementierung ist vorerst in populärem Python

Informationen zur Bereichsanforderung

In einigen Fällen akzeptiert der Server jedoch keine Bereichskopfzeilen.

Verwenden Sie diese Funktion, um verschiedene Teile einer Datei von mehreren TCP-Verbindungen gleichzeitig anzufordern

Multiplexing

Python verfügt über ein Modul namens Selektoren, das ausgewählte Systemaufrufe auf einer höheren Ebene verarbeiten kann (in der Standardbibliothek!). 18.4. Selektoren - Hohe Stufe des E / A-Multiplexing - Python 3.6.1-Dokumentation Überwachen und multiplexen Sie mehrere Steckdosen mit diesem Typen Verwenden Sie so

#Stellen Sie sich eine Verbindung mit zwei TCP-Echoservern vor, A und B.
import selectors
import socket

#Unterlassung
sel = selectors.DefaultSelectors()
sock_A = socket.create_connection(address_A)
sock_B = socket.create_connection(address_B)

sel.resister(sock_A, selectors.EVENT_READ)
sel.resister(sock_B, selectors.EVENT_READ)


sock_B.sendall('Hello'.encode()) # send something to A
sock_B.sendall('Hello'.encode()) # send something to B

while True:
    events = sel.select()
    for key, mask in events:
        message = key.fileobj.recv(512)
        print(message.decode())

Punkt

Rauer Fluss

  1. Senden Sie eine HTTP-HEAD-Anforderung, um die Dateigröße zu überprüfen (dies verwendet eine vorhandene HTTP-Bibliothek).
  2. Bestimmen Sie die Gesamtzahl der Divisionen und die Divisionsgröße und stellen Sie eine Verbindung her
  3. Senden Sie die erste Anfrage
  4. Überwachen Sie die Sockets mit den oben genannten Selektoren, lesen Sie nacheinander aus den lesbaren Sockets und legen Sie jeden Socket in den Primärpuffer.
  5. Wenn der Inhalt des Primärpuffers lang genug ist, um als HTTP-Antwort verarbeitet zu werden, teilen Sie ihn in einen Header und einen Body auf.
  6. Identifizieren Sie aus dem Header, welchem Teil der Datei die Antwort entspricht, und wechseln Sie vom primären zum sekundären Puffer
  7. Schreiben Sie von Anfang an in die Datei im sekundären Puffer und löschen Sie sie dann aus dem sekundären Puffer
  8. Aktualisieren Sie den Auswertungswert jeder Verbindung, verwerfen Sie die Verbindung mit geringer Leistung und senden Sie die Anforderung erneut an die neu hergestellte Verbindung.
  9. Wiederholen Sie die Schritte 4 bis 8, bis die gesamte Datei vollständig ist

Implementiert

https://github.com/johejo/rangedl Es gibt immer noch einige Fehler

Wie benutzt man

Umgebung Python 3.6.1

$ pip install git+http://github.com/johejo/rangedl.git
$ rangedl [URL] -n [NUM_OF_CONNECTION] -s [SPLIT_SIZE_MB]

Ergebnis

―― Abhängig von der Stimmung der Leitung konnte ich mit etwa 200 Mbit / s herunterladen.

Recommended Posts

HTTP Split Download Typ mit Python gemacht
HTTP-Kommunikation mit Python
Ich habe einen Blackjack mit Python gemacht!
Einfacher HTTP-Server mit Python
Ich habe mit Python einen Blackjack gemacht.
Othello gemacht mit Python (wie GUI)
Ich habe Wordcloud mit Python gemacht.
Laden Sie die CSV-Datei mit Python herunter
Mit Flask erstellte SNS Python-Grundlagen
Implementierter Dateidownload mit Python + Bottle
Numer0n mit Elementen, die mit Python erstellt wurden
Ich habe mit Python eine Lotterie gemacht.
Othello-Spieleentwicklung mit Python
Ich habe mit Python einen Daemon erstellt
Laden Sie Python herunter
CSV-Datei mit Python lesen (CSV-Datei herunterladen und analysieren)
Einfacher Slack API-Client mit Python
Ich habe mit Python einen Zeichenzähler erstellt
Laden Sie japanische Aktienkursdaten mit Python herunter
Laden Sie mit Python Dateien im Web herunter
Ich habe mit Python eine Hex-Map erstellt
Laden Sie einfach mp3 / mp4 mit Python und youtube-dl herunter!
Serverlose Gesichtserkennungs-API mit Python
Ich habe mit Python ein schurkenhaftes Spiel gemacht
Ich habe mit Python einen einfachen Blackjack gemacht
Ich habe mit Python eine Einstellungsdatei erstellt
Ich habe mit Python einen Neuronensimulator erstellt
Othello App (iOS App) erstellt mit Python (Kivy)
Mol2-Datei mit Python teilen (-> 17.04.2016. Unterstützt auch SDF-Datei)
[Python] Python und Sicherheit - Port-Scan-Tool mit Python
FizzBuzz in Python3
Suchen und laden Sie YouTube-Videos automatisch mit Python herunter
Scraping mit Python
Ich habe mit Python eine Bot-Wettervorhersage gemacht.
Statistik mit Python
Ich habe eine GUI-App mit Python + PyQt5 erstellt
Scraping mit Python
Python mit Go
Python Web Content mit Lolipop billigen Server gemacht
GUI-Bildschneidewerkzeug mit Python + Tkinter
Ich habe versucht, mit Python einen Twitter-Blocker für faule Mädchen zu machen
Twilio mit Python
Vorgehensweise zum Erstellen eines mit Python erstellten LineBot
In Python integrieren
Spielen Sie mit 2016-Python
[Python] Ich habe mit Tkinter einen Youtube Downloader erstellt.
AES256 mit Python
Getestet mit Python
Python beginnt mit ()
mit Syntax (Python)
Bingo mit Python
Zundokokiyoshi mit Python
Massen-Download-Bilder von einer bestimmten URL mit Python
Senden Sie HTTP mit dem Standardauthentifizierungsheader in Python
Excel mit Python
Mikrocomputer mit Python
Ich habe mit Python ein Bin-Picking-Spiel gemacht
Mattermost Bot mit Python gemacht (+ Flask)
Mit Python besetzen
Ich habe einen Twitter BOT mit GAE (Python) gemacht (mit einer Referenz)