Winsock -> Übertragung zu langsam.



  • 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