Winsock -> Übertragung zu langsam.



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



  • flammenvogel schrieb:

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

    Für die FAQ ist das zu Mager und zu Ungenau, das schmeckt ihr nicht.


Anmelden zum Antworten