Winsock -> Übertragung zu langsam.



  • 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.



  • flammenvogel schrieb:

    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 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.

    Hallo flammenvogel.

    Deine Implementation der funktion select() war damals wirklich ziemlich.. ähmmm.. sagen wir mal schlecht ;~).
    Du sagst du kennst dich mit Threads nicht aus und ich kann dir nur raten dir klar zu machen was Threads sind und wie Windows arbeitet. Threads sind unverzichtbar, wenn eine Funktion mehrere Minuten nimmt. Dann musst du die Ausführung dieser Funktion in einen separaten Thread packen, um zu verhindern dass deine GUI 'erstarrt' oder sogar dein Programm von Windows abgeschossen wird, weil es auf die Messages in der Messagequeque nicht reagieren kann.

    Threads erstellst du einfach mit CreateTHread() und die Synoycronisation (habs falsch getippt, ich weis ;)) kannst du dir in den meisten Fällen schenken. Du machst das einfach mit ner Indikator Variable des Typs boolean. Im Thread läuft ne 'endlos' Schleife die nur dann abbricht wenn diese globale Indikatorvariable false ist und zum beenden des Threads von aussen stellt man einfach diese Variable auf false und der Thread läuft aus, d.h. beendet sich automatisch. Wenn der Thread sich selbst beenden soll stellt er einfach diese Variable selbst auf false und bei der nächsten Iteration murkst er ab! 😉

    MfG.



  • Wenn man WSAAsyncSelect benutzt, brauch man keine Threads. :p



  • Das ist leider nicht richtig. Wenn du eine 200MB Datei mit der send() funktion überträgst, so beansprucht das Zeit. Viel Zeit! In dieser Zeit kann Dein Programm -weil es ja alles in einem Thread tun soll- zur selben Zeit entweder die WndProc bearbeiten und damit seine MesssageQueque abbauen, oder die 200MB Datei übertragen.

    Beides Gleichzeitig geht nicht, da send blockiert und in dieser blockierten Zeit sieht dein Programm für WIndows so aus,als würde es hängen und wenns die WndProc nicht mehr abarbeiten kann finde ich persönlcih auch das man sagen kann dass es hängt. Kein Userinput mehr möglich, nicht mal beenden kann man es in dieser Zeit!

    Dann wird dein Programm einfach vom Betriebssystem abgeschossen.

    Wie du siehst bist du daraus angewiesen die Übertragung mit send() auf einen andneren Thread auszulagern.

    MfG.



  • Du hast das Prinzip hinter WSAAsyncSelect nicht verstanden.



  • WSAAsyncSelect schrieb:

    Du hast das Prinzip hinter WSAAsyncSelect nicht verstanden.

    Ich hab das Gefühl ich auch nicht - Klär mich auf!



  • Du bekommst immer Benachrichtigungen wenn du etwas senden kannst oder was empfangen kannst. Dort kannst du dann send bzw. recv aufrufen. Aber diese Funktionen werden *niemals* blocken. Entweder es wird alles übertragen/empfangen oder die Funktionen schlagen mit SOCKET_ERROR fehl und WSAGetLastError gibt WSAEWOULDBLOCK zurück. Dann wird man "später" wieder benachrichtigt.



  • WSAAsyncSelect schrieb:

    Wenn man WSAAsyncSelect benutzt, brauch man keine Threads. :p

    .....erstellen!

    stimmt, da winsock entsprechende Threads erstellt und syncronisiert.



  • Ja ist mir auch nach meinem Beitrag eingefallen. Aber Winsock erstellt doch nur einen Thread für alle asynchronen Sockets oder?



  • @WSAAsyncSelect: thx, nu hab ichs glaube ich geschnallt...

    ...aber irgendwie gefällt mir die Thread-Methode mit select() trotzdem besser.
    Und ich behaupte: Bei vielen Verbindungen und Daten wird das GUI dann trotzdem ausgebremst, da das Fenster dann quasi mit Events beschossen wird 😉



  • Und ich behaupte: Bei vielen Verbindungen und Daten wird das GUI dann trotzdem ausgebremst, da das Fenster dann quasi mit Events beschossen wird 😉

    Ja das würde ich mich auch mal interessieren. Habe damit auch noch kaum Erfahrung. Aber wenn ich so ein Problem hätte dann würde ich wahrscheinlich einen Thread mit einem unsichtbaren Fenster nutzen und dann trotzdem WSAAsyncSelect weil es gegenüber der select Methode meiner Meinung einfacher in der Benutzung ist. 🙂



  • @WSAAsyncSelect : Danke für die Aufklärung.
    @geeky: Danke für die Lösung meines Übertragungsproblems.

    Für Interessierte hier das Problem, das Geeky via ICQ gelöst hat ;~)
    :

    Ich hatte nicht bedacht, dass mit send() verschickte Nachrichten von TCP zerlegt und Päckchenweise an den Server geschickt werden und habe nicht bedacht, dass select() den recv()-befehl schon ab dem ersten TCP-Päckchen auslöst.

    So erklärt sich auch von selbst, warum es funktionierte, als ich winzige Pakete versendet habe. Ein winziges Paket passte nämlich in ein einziges TCP-Paket (Datagramm) und somit hat recv() immer da GANZE geschickte Paket eingelesen.
    Bei Paketgrößen die TCP in mehrere Datagramme zerlegte kam es dazu, dass recv() nicht das gesamte Paket einlesen konnte, weil ja nicht alle Teile des Pakets gleichzeitig eintrffen, sodnern recv() hat lediglich die ersten paar Datagramme des Pakets bekommen.

    Nun fülle ich ein Datenpaket so lange mit recv() weiter bis es wirklich voll ist und alles läuft bestens. Auch die GO-On-Messages sind nun Geschichte und die Übertragung ist. ca. 8-10 mal schneller, da nun erstens die Netzwerkverzögerung durch die go-on messages entfällt, zum zweiten meine MTU 4KB ist statt 1KB.

    Thx @ Geeky.

    -------------------------- Problem gelöst -> Thread beendet. -----------------



  • WSAAsyncSelect schrieb:

    Ja ist mir auch nach meinem Beitrag eingefallen. Aber Winsock erstellt doch nur einen Thread für alle asynchronen Sockets oder?

    Je Socket einen Thread, die über einen Thread syncronisierd werden.

    geeky schrieb:

    Und ich behaupte: Bei vielen Verbindungen und Daten wird das GUI dann trotzdem ausgebremst, da das Fenster dann quasi mit Events beschossen wird 😉

    Nein, die Events laufen nicht in dein Programm, sondern in den Socket-Threads, du kannst das jeweilige Event, btw. Status eines Sockets abfragen, z.B. über einen Timer, der alle 200ms fragt ob alles OK ist, oder Daten senden/empfangen fertig ist etc.



  • Und bei send musst du glaub ich genau das selbe tun.



  • Je Socket einen Thread, die über einen Thread syncronisierd werden.

    Glaub ich nicht, aber ich werd es einfach selber mal testen.

    @all: Den Link find ich ganz interessant:

    http://tangentsoft.net/wskfaq/articles/io-strategies.html



  • Ja, der Link ist interessant. Bei www.c-worker.ch wird jedoch gesagt, select() sei eine höchst elegante Lösung und können sehr viele Sockets gleichzeitig betreuen.
    Für uns Kleinmänner wollte es deswegen kaum nen Unterschied machen, welchen Weg wir nehmen, es sei denn jmd. hat ein großes Projekt und erwartet paar Tausende Connections gleichzeitig aufm Servr ;~)

    Ich habe auf der Seite deren Link du geshcickt hast unten auf "next" geklickt und habe folgende wunderschöne Seite gefunden. Die sollte sich JEDER Lesen. Die die es schon wussten können ihr Wissen bestätigen, die andern lernen was 'lebeswichtiges'.

    http://tangentsoft.net/wskfaq/articles/effective-tcp.html

    MfG.



  • Vielleicht wäre ja für dich auch ein Thread pro Client gut. Dann ist die Programmierung richtig einfach. 🙂



  • Eigentlich wäre das mal was für die WinApi FAQ da ist nämlich noch nicht allzuviel über Winsocks drin.


Anmelden zum Antworten