Winsock -> Übertragung zu langsam.



  • Hallo.

    habe ein Client-Server Programm, das Daten leider zu langsam übermittelt.
    Ich sende immer Pakete von je 1500 Bytes d.h. ca. 1,5 KB;

    Sobald der Server das Paket bekommen hat schickt der dem Client eine 'Go_On_Message" und der Client schickt das nächste Paket.

    Falls jmd. einwendet, das mit der Go-On-Mesage sei unnötig, so kann ich dem sagen, die muss da sein. Denn ankommende Pakete werden vom Server auf gültigkeit überprüft und sollte ein Paket ungültig sein wird dem Client gesagt er soll das letzte Paket noch einmal senden. Bei 5 falschen paketen nacheinander wird die Verbindung zum Clienten beendet (Schutz gg. DoS Attacken).

    Was könnte ihc verbessern um den Speed anzuheben?

    MfG



  • Du müsstest dem Client erlauben, mehr als ein Paket gleichzeitig auf die Reise zu schicken. Ansonsten ist der limitierende Faktor die Verzögerung der Leitung.

    btw: Die Go-On-Nachricht ist IMHO wirklich überflüssig, denn die Daten auf Gültigkeit überprüfen und bestätigen macht schon TCP. 🙄



  • cd9000 schrieb:

    Du müsstest dem Client erlauben, mehr als ein Paket gleichzeitig auf die Reise zu schicken. Ansonsten ist der limitierende Faktor die Verzögerung der Leitung.

    btw: Die Go-On-Nachricht ist IMHO wirklich überflüssig, denn die Daten auf Gültigkeit überprüfen und bestätigen macht schon TCP. 🙄

    zu 1.) Die Sache ist die, dass es technisch unmöglich ist mehrere Pakete gleichzeitig zu senden. Ich könnte höchstens die Größe des gesendetens Pakets erhöhen aber mir wurde genau das gegenteil von nem Freund empfohlen der eine Verkleinerung der Pakete empfiehlt. Meine Test haben ergeben, dass alles über 3KB zu extrem oft auftretenden Übertragunsfehlern führt. Ist ja auch logisch. Je größer das Paket, umso größer die Wahrscheinlichkeit dass ein Byte falsch oder garnicht übertragen wird.

    zu 2.) Die go-on-Nachricht ist unverzichtbar um die Verbindung stabil zu Halten. Sobald ein kaputtgegangenes Paket beim Server ankommt verlangt dieser vom Client ne Erneute Zusendung des letztens Pakets. Wenn das Paket i.O war wird gesagt: "Go-on" und der Client schickt das nächste Paket. Ich kann mir auch nicht erklären warum TCP-Übertragungskontrolle die Fehler nicht verhidnern kann ABEER eines ist SICHER: Wenn du ein 2 KB Paket überträgst kommt ca. bei jedem 500sten Paket ein Fehler. D.h. der Inhalt geht kaputt. Da ich vermute, dass daran liegt, dass für die Queque von recv() zu große datenteile einfach weggeschmissen werden und so meine Pakete kaputtgehn. Und ganau das fang ich mit der Kontrolle der Pakete ab. Die Go-On mesage ist Teil dieser Kontrollroutine.

    PS: Ich kenne mich mit TCP / UDP / ICMP aus... aber leider nur in der Theorie und habe nie zuvor ein echtes Netzwerkprogramm programmiert (Ausnahme: ein kleiner multiuserchat).



  • loooool junge wenn du wüsstest was du fürne scheisse redest würdest du dich warscheinlich selber schlagen....

    sicher recv() schmeisst die halben packete weg das is immer so denn recv() kann dich nicht leiden!!! überleg mal wie du netzwerkprogramme schreiben willst wenn die funktionen die halben packete wegschmeissen

    groß bei den anderen posts klugscheissen aber selber so´n scheiss reden und wenn dir wer helfen will den auch noch blöd anmachen

    aber macht nix spam das netzwerk mit deinen "Go-On" Messages voll der admin wirds dir danken...

    mfg



  • hallo,

    zu 2.)
    so SICHER ist das nicht, da müßte ja jeder Server so programmiert sein.

    Hatte auch mal das Problem, jeden Datensatz einzeln übertragen und vom Server bestätigen lassen ...

    hab es jetzt so, ich sende eine CRC über die folgenden Daten und dann die Daten gezippt in Blöcken so groß wie es halt geht und die kommen alle an, nix ca. 500 Packete und Fehler ...

    Was geht es eigentlich send und revc an wie groß der zu übertragende Block ist
    wenn mein Puffer 1MB ist wird dieser send() übergeben, was send dann damit macht ist doch wurscht

    MfG
    RB



  • Das mit den Go on Nachricht ist wirklich völliger Quatsch bei TCP/IP. Du solltest dich lieber bemühen den richtigen Fehler zu finden.



  • recv schrieb:

    Das mit den Go on Nachricht ist wirklich völliger Quatsch bei TCP/IP. Du solltest dich lieber bemühen den richtigen Fehler zu finden.

    Ich habe sehr lange gesucht bevor ich dem Problem mit der go-on-msg ausgewichen bin. Nun suche ich nach ner Methode den Speed zu erhöhen. Wenns nicht geht mit einsatz der go_on message wede ich das projekt auf eis legen.

    Das Projekt habe ich vor ca. 1 Jahr gestartet und seit 7 Monaten nicht damit gearbeitet. Seit paar Tagen habe ich die Lust und Zeit und hab mich d rangesetzt. 4,5 Tausend Zeilen Code. Davon ca. 500 für Netzwerkfunktionen...
    Da findet man keinen Fehler mehr... zumindest kostet es Nerven..

    Naja.. ich habe das Gefühl, es geht ohne Beseitigung der go-on-sache nicht schneller. Das haben bisher einige gesagt. Dann werde ich wohl zusehn dass ich das gesamte Netzwerkmodul einfach ganz neu mache...

    Hätte ich die vergeblich-debug - Zeit in ein neues Modul gesteckt hätte ich es sicher 3 mal fertiggestellt..

    Danke für eure Antworten.

    Mfg.



  • Darf man wissen wofür du 500 Zeilen Code in einem Netzwerkmodul benötigst? Was baust du denn so spannendes 🙂

    MfG SideWinder



  • Hallo.

    Ich programmiere einen Trojaner!

    MfG.



  • Der Typ der sich da als ich ausgibt ist Nero. Die Admins oder Mods werden das an den IP's auch sehen!!!

    Ich Programmiere einen Server mit eigenem Protokoll, der auch das Windows steuern kann ABER hat NICHTS mit trojanern zutun, da das ganze am ende ehh opensource wird.

    Mfg.



  • oh, ein Opensource-Trojaner 😉



  • Hallo.

    Ok, ich hab dich zwar gefakt, aber ich bin nicht Nero. :p

    MfG.



  • Eigentlich sollte die Überbertragung von send und recv immer Fehlerfrei verlaufen. Ich schreibe jetzt selber an eine Klasse rum damit meine Progs auf das Netzwerk zugreifen können und ich habe es auch auf mind 300-400 Zeilen gebracht. Allerdings solltest du mit WSAAsyncSelect es in weniger Code zeilen schaffen. Den die Funktion switch bringt es nicht wirklich. (Ich nehme mal an du benutzt switch). Wieso teilst du den Kram in Pakete auf. Ein Paket mir vordefinierter Standardgröße zum Server senden der die Größe des "Daten" Paketes enthält und dann alles aufeinmal senden.



  • Welche Funktion switch? Ich glaube du hast keine Ahnung. 😃



  • flammenvogel schrieb:

    (...)Allerdings solltest du mit WSAAsyncSelect es in weniger Code zeilen schaffen. Den die Funktion switch bringt es nicht wirklich. (Ich nehme mal an du benutzt switch). Wieso teilst du den Kram in Pakete auf. Ein Paket mir vordefinierter Standardgröße zum Server senden der die Größe des "Daten" Paketes enthält und dann alles aufeinmal senden.

    Hallo flammenvogel.

    Du meinst sicherlich die Funktion select(). Ja deine Annahme ist richtig, ich benutze select und denke auch, dass select die eleganteste Lösung ist.
    Was du vorschlägst wird generell ausschließlich für Apllikationen kleinen Umfangs wie. z.B. Windowstools wie ping.exe und ähnliches empfohlen.

    Siehe dir mal den Tutorial bei c-worker.ch an (ich hoffe so hieß die seite)..

    MfG.



  • @tolga: Deine Funktion in der du recv() verbaut hast scheint fehlerhaft zu sein (oder du sendest es schon falsch...)
    Auf jedenfall ist eine GoOn-Nachricht bei TCP eigentlich völlig überflüssig und bremst sogar. Kleinere Pakete bringen imho überhaupt nichts, wenn die Pakete zu groß sind zerhackstückelt Windows, dein Router oder sonstwas die Pakete automatisch in kleinere...



  • geeky schrieb:

    @tolga: Deine Funktion in der du recv() verbaut hast scheint fehlerhaft zu sein (oder du sendest es schon falsch...)
    Auf jedenfall ist eine GoOn-Nachricht bei TCP eigentlich völlig überflüssig und bremst sogar. Kleinere Pakete bringen imho überhaupt nichts, wenn die Pakete zu groß sind zerhackstückelt Windows, dein Router oder sonstwas die Pakete automatisch in kleinere...

    Hallo Geeky.

    Ich denke auch, das ich einen Fehler bei der send() oder recv() implementation gemacht habe.
    Bin gerade dabei diese beiden Funktionen neu zu schreiben. Da habe ich nun ne kleine Frage im Hinterkopf.

    Bisher habe ich ja keine c-schleife bei der Übetragung benutzt sondern bei jeder go-on-msg das nächste Paket übertragen.
    Nun mache ichs wieder mit ner

    while (FileSize!=Transmittedbytes)
    {
    
    }
    

    Wenn ich ne 100MB Datei übertrageen würde, würde dann diese Schleife nicht den Netzwerkthread blockieren und verhindern dass während der Übertragung der Server dem Client was schickt? Weil die beim Client ankommenden Messages könnte dieser erst dann sehen, wenn er die Übertragungsschleife wieder verlassen hat?

    Sollte ich vll. 2 netzwerkthreads machen?
    Eins für Datenübertragung....
    Eins für Client-Server-Kommunikation.

    Hmm...



  • Deinem letzen Posting entnehme ich das du, das ganze mit Threads gelöst hast.

    Das mit den zwei Threads halte ich für keine gute Idee das ist das Funktionsprinzip vom FTP Protokoll und ich persönlich halte das für qwatsch. Dann musst du hier und dort Critical Sections für die Kommunikation einbaunen. Und dann wartet der eine Thread wieder auf den anderen und das ist wie gesagt nicht so gut.

    Achja ich meinte select nicht switch, sorry. Ich habe es damals versucht mit select und timeout nahe null versucht, was relativ schwachsinig ist. Warum hälst du eine Lösung mit WsaAsyncSelect für ungegeignet???



  • flammenvogel schrieb:

    Deinem letzen Posting entnehme ich das du, das ganze mit Threads gelöst hast.

    Das mit den zwei Threads halte ich für keine gute Idee das ist das Funktionsprinzip vom FTP Protokoll und ich persönlich halte das für qwatsch. Dann musst du hier und dort Critical Sections für die Kommunikation einbaunen. Und dann wartet der eine Thread wieder auf den anderen und das ist wie gesagt nicht so gut.

    Achja ich meinte select nicht switch, sorry. Ich habe es damals versucht mit select und timeout nahe null versucht, was relativ schwachsinig ist. Warum hälst du eine Lösung mit WsaAsyncSelect für ungegeignet???

    Hallo flammenvogel.

    Ich weis nicht was du meinst. Ich habe den Server mit select erstellt, d.h. es exestiert nicht für jeden Socket ein Thread.
    Ich habe sicher 2 Threads. Ein GUI-Thread und ein Netzwerk-Thread.

    Wenn du dich auskennst, sag mal ob die sache mit der While-schleife die beste Lösung ist für einen kleinen Server.

    Ich halte eine Lösung mit WsaAsyncSelect nicht für ungeeignet, da ich mir dei Funktion nie näher angesehn hab und was ich nicht kenne kann ich ja kaum als ungeeignet bewerten.

    Ich werde das mit select machen und mein Problem hat damit überhaupt garnichts zutun. Das Annehmen eingehender Connections klappt ehh wunderbar. Warum sollte ich jetzt den funktionierenden Teil umbauen.
    Ausserdem finde ich wie schon gesagt select schöner.

    MfG.



  • ne das was ich meinte basiert nicht auf threads, ich habe das so programmiert das select ein paar msec auf ein netevent wartet, wenn keins kommt abbricht und dann die GUI Sachen abarbeitet und dann wieder select aufruft (also ziemlich schwachsinnig).

    Ich finde WSAAsyncSelect nur gut da du in jedem WinAPI Programm mit GUI ja eine Schleife hast für die ganzen Windowsmessages. Wenn du jetzt WSAAsyncSelect aufrufst sendest du dir selbst auch Nachrichten wenn im Netzwerk was geschieht. So kannst du das dann in der gleichen Schleife abarbeiten und du brauchst keine zwei Thread die du sowieso wieder irgendwie syncroniseren musst. (Ich kenne mich mit Thread Programmierung nicht so aus). Daher finde ich die Variante mit WSAAsyncSelect passender.

    Vorher habe ich wie gesagt versucht das Problem wie oben beschrieben nur mit select und ohne Threads zu lösen.

    Aber nochmal zu deinem Problem. Es ist völlig überflüssig, das Prinzip mit den GoOn Messages. Da die TCP Schicht sich um die Korrekte übertragung kümmert es macht keinen Sinn das nochmal zu machen. Auch das "zerhackstückeln wird von TCP übernonmmen (Stichwort MTU). Also wäre es wie oben beschrieben problemlos möglich eine Nachricht mit der Größe der ganzen Datei an den Empfänger zu senden und dann die Datei mit einem send Aufruf zu übertragen. (Wenn du ne Progress Bar brauchst kannst auch in Kb aufteilen und die hintereinander weg senden.)

    Kann es sein das du in deiner Klasse/Header das TCP Protokoll neu implementiert hast. Das ist IMHO mit WinSock möglich.


Log in to reply