Protokoll zum Dateitransfer gesucht



  • scrontch schrieb:

    Ok. Danke für die Beiträge.
    Also wird es HTTP.
    Welche leichtgewichtigen Libs gibt's da für C++ unter Windows?

    libcurl

    Ansonsten gibt es auf der libcurl-Homepage eine Liste von Alternativen: http://curl.haxx.se/libcurl/competitors.html



  • scrontch schrieb:

    Hallo,

    In einer Anwendung soll ein Client eine Binärdatei von einem Server herunterladen. (Die Binärdatei ist eine exe-Datei, die ein Update für den Client darstellt. Die Dateigrösse liegt so im 1-MB-Bereich).
    Das ganze läuft im LAN, also einer kontrollierten Umgebung.
    Welches Protokoll würdet ihr einsetzen?
    Das ganze sollte möglichst einfach zu implementieren sein für Client und Server, d.h. Zugriff auf bestehende Open-Source Bibliotheken wenn's geht.

    HTTP oder FTP erscheinen mir bisher als Overkill.
    (bei HTTP muss man Header parsen, bei FTP gibt's separate Command- und Daten-verbindungen - alles sehr kompliziert)
    Oder gibt's da "leichte" Implementierungen?
    TFTP würde von der Komplexität her ausreichen, aber was TCP-basiertes wäre mir lieber.
    Wie würdet ihr sowas machen?

    Das wohl Einfachste wäre:
    1. Client connected sich auf den Server über TCP.
    2. Server schiebt Datei rüber, Rohdaten, ohne zusätzliches Protokoll.
    3. Client liest den Datenstrom und speichert alles in eine Datei.
    4. Server schließt die Verbindung, wenn er das letzte Byte versendet hat.
    5. Client bemerkt das Schließen vom Server und weiß somit, dass die Übertragung beendet ist.

    Du brauchst dazu keinerlei Librarys, bloß ganz gewöhnliche Socket-Operationen. TCP sorgt schon dafür, dass alles fehlerfrei übertragen wird.



  • @Z So kannst du aber keine Fehlercodes oder Ähnliches übertragen. 🙂
    @scrontch
    Ich würde mir da eben etwas Eigenes basteln. Eben auf den Status Code und dann auf Content-Length gucken ist ja jetzt nicht so der Aufwand, eine Lib die mal eben das gesamte HTTP-Protokoll implementiert ist da meiner Meinung nach schon zu viel.



  • cooky451 schrieb:

    @Z So kannst du aber keine Fehlercodes oder Ähnliches übertragen. 🙂

    Damit kannst du alles übertragen, das sich in Form von Bits und Bytes darstellen lässt.



  • Z schrieb:

    cooky451 schrieb:

    @Z So kannst du aber keine Fehlercodes oder Ähnliches übertragen. 🙂

    Damit kannst du alles übertragen, das sich in Form von Bits und Bytes darstellen lässt.

    So wie du es beschrieben hast nicht, da du nur den Inhalt des Files berträgst.
    Wenn der Server lieber ne Fehlermeldung schicken würde, hätte der Client keine Chance diese von einer Datei mit dem selben Inhalt & Länge zu unterscheiden.

    Du musst dein Protokoll also entsprechend erweitern.



  • hustbaer schrieb:

    Z schrieb:

    cooky451 schrieb:

    @Z So kannst du aber keine Fehlercodes oder Ähnliches übertragen. 🙂

    Damit kannst du alles übertragen, das sich in Form von Bits und Bytes darstellen lässt.

    So wie du es beschrieben hast nicht, da du nur den Inhalt des Files berträgst.
    Wenn der Server lieber ne Fehlermeldung schicken würde, hätte der Client keine Chance diese von einer Datei mit dem selben Inhalt & Länge zu unterscheiden.

    Beim Übertragen von Dateien über TCP sind doch nur 4 Fehler möglich: Verbindung kann nicht aufgebaut werden, keine Datei vorhanden, Verbindung vorzeitig abgebrochen, oder Timeout. Das alles sollte sich einwandfrei erkennen lassen, auch ohne dass man die Daten in ein zusätzliches Protokoll einpackt.



  • Also ich halte das nicht für sinnvoll...
    Ne kleine Header wo z.B. der Erfolgs/Fehlercode und die Länge der folgenden Datei drinnen steht, dann der Dateiinhalt, und ne schöne Prüfsumme hinten nach - das tut doch keinem weh.



  • hustbaer schrieb:

    Also ich halte das nicht für sinnvoll...
    Ne kleine Header wo z.B. der Erfolgs/Fehlercode und die Länge der folgenden Datei drinnen steht, dann der Dateiinhalt, und ne schöne Prüfsumme hinten nach - das tut doch keinem weh.

    Wenn er sowieso libcurl o.ä. nimmt, kann er gleich HTTP benutzen, wie bereits vorgeschlagen. Dann kann er die Datei sogar mit einem Webbrowser downloaden, wenn es denn mal sein muß.

    Aber Prüfsummen sind bei einer Übertragung über TCP in der Regel überflüssig.



  • Z schrieb:

    hustbaer schrieb:

    Also ich halte das nicht für sinnvoll...
    Ne kleine Header wo z.B. der Erfolgs/Fehlercode und die Länge der folgenden Datei drinnen steht, dann der Dateiinhalt, und ne schöne Prüfsumme hinten nach - das tut doch keinem weh.

    Wenn er sowieso libcurl o.ä. nimmt, kann er gleich HTTP benutzen, wie bereits vorgeschlagen. Dann kann er die Datei sogar mit einem Webbrowser downloaden, wenn es denn mal sein muß.

    Ich wollte ursprünglich bloss darauf hinweisen, dass deine Antwort an cooky451 nicht zu deinem eigenen Vorschlag passt lediglich die Datei zu übertragen, und die Grösse beim Client implizit per "connection close" zu ermitteln.

    Aber Prüfsummen sind bei einer Übertragung über TCP in der Regel überflüssig.

    TCP hat selbst keine starke (ernstzunehmende) Prüfsumme.
    Dass trotzdem so wenig Fehler passieren, kann eigentlich nur daran liegen, dass die darunterliegenden Schichten bereits ausreichend gut abgesichert sind.
    Ich würde auf jeden Fall empfehlen eigene Prüfsummen mitzuschicken.



  • Z schrieb:

    Beim Übertragen von Dateien über TCP sind doch nur 4 Fehler möglich: Verbindung kann nicht aufgebaut werden, keine Datei vorhanden, Verbindung vorzeitig abgebrochen, oder Timeout. Das alles sollte sich einwandfrei erkennen lassen, auch ohne dass man die Daten in ein zusätzliches Protokoll einpackt.

    Wie erkennst Du denn, dass eine Verbindung vorzeitig abgebrochen wurde? Und wie unterscheidest Du eine Datei mit der Länge 0 mit einer fehlenden Datei?



  • ich bins schrieb:

    Wie erkennst Du denn, dass eine Verbindung vorzeitig abgebrochen wurde?

    Gewöhnliche Socket-Read-Funktionen liefern einen unterschiedlichen Statuswert zurück, wenn die Verbindung abbrach, oder regulär geschlossen wurde.

    ich bins schrieb:

    Und wie unterscheidest Du eine Datei mit der Länge 0 mit einer fehlenden Datei?

    Diese Unterscheidung ist nicht notwendig. Was möchtest du mit dem Inhalt einer Datei der Länge 0 denn machen?



  • Z schrieb:

    ich bins schrieb:

    Und wie unterscheidest Du eine Datei mit der Länge 0 mit einer fehlenden Datei?

    Diese Unterscheidung ist nicht notwendig. Was möchtest du mit dem Inhalt einer Datei der Länge 0 denn machen?

    Lol.
    Die Unterscheidung ist in vielen Situationen nicht nötig.
    In anderen aber sehr wohl.

    Deine allgemeine Aussage "ist nicht notwendig" ist daher grosser Quatsch.



  • hustbaer schrieb:

    Z schrieb:

    ich bins schrieb:

    Und wie unterscheidest Du eine Datei mit der Länge 0 mit einer fehlenden Datei?

    Diese Unterscheidung ist nicht notwendig. Was möchtest du mit dem Inhalt einer Datei der Länge 0 denn machen?

    Lol.
    Die Unterscheidung ist in vielen Situationen nicht nötig.
    In anderen aber sehr wohl.

    Deine allgemeine Aussage "ist nicht notwendig" ist daher grosser Quatsch.

    Es geht hier aber um einen konkreten Fall (siehe ersten Beitrag des Threads). Nenn doch bitte mal einen Grund, wieso der Server des OP eine Datei der Länge 0 senden sollte.



  • Weil die Datei Indikator fuer die Existenz von bestimmten Dingen sein koennte. Siehe Unix-Derivate



  • otze schrieb:

    Weil die Datei Indikator fuer die Existenz von bestimmten Dingen sein koennte. Siehe Unix-Derivate

    Das hat aber nichts mit der Aufgabenstellung des OPs zu tun, dessen Client eine Datei sinnvollen Inhalts benötigt.

    Btw, Anhand des Verhaltens des Servers bei der Verbindungsaufnahme, ließe sich dem Client übrigens tatsächlich mitteilen, ob keine Datei, oder eine der Länge 0 auf dem Server schlummert. Wir brauchen diese Unterscheidung hier aber trotzdem nicht.



  • Ich denke es wäre sicherer, ein einfaches Protokoll drumrum zu basteln. Es könnte beispielsweise so aussehen:

    GET /datei.txt MYFTP/1.0
    

    Antwort:

    Content-Length: 4711
    
    ...daten...
    

    Ich denke, das ist recht einfach zu implementieren und könnte später erweitert werden.

    Ach - mir fällt gerade auf, dass man ja statt MYFTP auch HTTP schreiben könnte. Dann wäre es ja so gar zufälligerweise HTTP. Dann ist das ja möglicherweise doch nicht so mit Kanonen auf Spatzen geschossen 😉 .



  • Z schrieb:

    Btw, Anhand des Verhaltens des Servers bei der Verbindungsaufnahme, ließe sich dem Client übrigens tatsächlich mitteilen, ob keine Datei, oder eine der Länge 0 auf dem Server schlummert. Wir brauchen diese Unterscheidung hier aber trotzdem nicht.

    Ja man kann viel machen.
    Es kann aber auch viel in die Hose gehen, weil andere Komponenten (Router, Bridges, ...) andere (u.U. nicht standardkonforme) Vorstellungen davon haben wie bestimmte Dinge abzulaufen haben.

    Sich da auf ein bestimmtes Verhalten zu verlassen ist mMn. einigermassen riskant.

    Das hat aber nichts mit der Aufgabenstellung des OPs zu tun, dessen Client eine Datei sinnvollen Inhalts benötigt.

    Es wurde glaub ich nirgends gesagt (geschrieben), dass die Datei immer > 0 Byte gross sein wird/muss.
    Das nächste Glücksspiel.



  • ich bins schrieb:

    (...)
    Ach - mir fällt gerade auf, dass man ja statt MYFTP auch HTTP schreiben könnte. Dann wäre es ja so gar zufälligerweise HTTP. Dann ist das ja möglicherweise doch nicht so mit Kanonen auf Spatzen geschossen 😉 .

    Einen vollständigen HTTP Server oder Client zu implementieren ist um ein vielfaches mehr Aufwand als das.
    Und eine "geht mit den meisten anderen Servern/Clients" Lösung ist IMO nicht sinnvoll.
    Dann lieber gleich libcurl/NEON/...



  • hustbaer schrieb:

    Einen vollständigen HTTP Server oder Client zu implementieren ist um ein vielfaches mehr Aufwand als das.

    Nein. Das sind keine 5 Minuten arbeit. Weil es für HTTP schon alles fertig gibt.
    2 Minuten mit Node.js einen Server geschrieben der dir die Dateien ausliefert und in 2 Minuten mit libcurl oder einer der anderen 100mio HTTP Client Implementierungen den Client Code geschrieben. In vielen File-Libraries gibt es zB sogar nativen Support für HTTP Requests.

    Und man muss den Server oder Client ja nichtmal selber schreiben. curl/wget auf der Client Seite und lighthttpd oder den nativen HTTP Server des Host OS.

    Deshalb würde ich hier prinzipiell erstmal HTTP wählen. Wenn das nicht 100% passt würde ich erstmal bei HTTP bleiben und wenn es akute Probleme gibt mir ernsthaft überlegen ob HTTP nicht die beste Lösung ist. Und dann erst nach Alternativen suchen.



  • hustbaer schrieb:

    Dann lieber gleich libcurl/NEON/...

    Shade Of Mine schrieb:

    Nein. Das sind keine 5 Minuten arbeit. Weil es für HTTP schon alles fertig gibt. [..] Deshalb würde ich hier prinzipiell erstmal HTTP wählen.

    Zum Glück sind wir alle einer Meinung. 😃


Anmelden zum Antworten