TCP Listener Sehr viele Daten empfangen



  • Keiner eine Idee?



  • Da die Schreiboperationen in die Datenbank vermutlich alle blockierend sind, reicht dafür ein Thread. Also ein Thread für die Kommunikation und einer für die Datenbankzugriffe.



  • Welches ist den Richtig. Es soll nämlich auch zum Beispiel mehrere Clients gleichzeitig handeln können.

    Viele Wege fuehren nach Rom, manche via Threads, andere ueber Prozesse und wieder andere ueber select.

    Also soll ich für das empfangen keine Threads aber für das eintragen in die DB Threads verwenden?? Soll ich also ...

    Es gibt kein soll, nur ein guenstig oder unguenstig. Klar kannst du 2000 Threads benutzen, aber ob es unguenstig, kann pauschal nicht gesagt werden.

    aber ich habe gelesen das wenn ich Threads benutze es Probleme geben kann.

    Was meinst du? Mit einem Brotmesser kann es auch Probleme geben.



  • Könntest auch Erlang nehmen 🙂 Da erübrigt sich das ganze Thread-Zeugs komplett.



  • Ich würde das lieber nicht mit Windows machen. Linux und dev/epoll sind am besten skalierbar, selbst select hätte unter Linux maximal 1024 mögliche Verbindungen, Windows nur 64. Wenn es richtig performant werden soll (für Windows): Thread-Pools und IO-Completion Ports. Ob das im Gegensatz zu Linux performant ist? Eher nicht. Wie wäre es mit Apache + Python/PHP? Dann wärst du die Socket-Probleme etwas los, denn wenn du dich damit noch nicht auskennst, ist es unwahrscheinlich, dass dein Resultat auf Anhieb super ist, deshalb empfehle ich, vorhandene Server zu nutzen.



  • @Ad aCTa
    ist kein wirkliches Argument, man kann ja select mehrfach aufrufen. Außerdem hängt die Maximalanzahl Sockets pro select afaik nur von FD_SIZE ab, das kann man ja auf einen beliebigen Wert setzen.
    Sinnvollerweise hat man ein oder zwei Threads, die alle Daten einsammeln und einen weiteren, der das Zeug in der Datenbank verstaut.



  • > das kann man ja auf einen beliebigen Wert setzen.

    Nein, die fd_sets sind AFAIK intern Bitfelder, die du nicht willkürlich verändern kannst.

    > ist kein wirkliches Argument, man kann ja select mehrfach aufrufen.

    Wenn sie nicht blockieren, ja. Non-blocking-selects sind aber nun wirklich nicht die Bombe was Leistung angeht.

    http://www.fefe.de/scalable-networking.pdf



  • FD_SIZE ist ein Makro, das dann wohl die Feldgröße bestimmt.
    Und naja, select ist doch genau dazu da, um bei blocking sockets herauszufinden, welche von ihnen gerade "bereit" zum Empfangen/Senden sind.



  • > FD_SIZE ist ein Makro, das dann wohl die Feldgröße bestimmt.

    Exakt, aber AFAIK ist das read-only gedacht, wegen Bitfeldern. Mit Linux könnte man es tatsächlich ändern, danach muss aber der ganze Kernel neu kompiliert werden, was bei Windows schwierig werden könnte. Du könntest mehrere fd_sets nutzen und mit mehreren selects() und mit timeouts evtl. was werkeln, aber 32 selects mit timeouts finde ich nicht skalierbar, dann warten sie letzten fd's alle timeouts ab, bis sie drankommen. Threads verschlimmbessern das m.E. dann auch nur noch.



  • Entweder 64 Verbindungen pro Thread oder eben weniger Threads und einen sofortigen Timeout und evtl. ein (sehr) kurzes Sleep ganz am Ende um die CPU etwas zu schonen.
    Bei 2000 Verbindungen muss man sich noch nicht so den Kopf über Performance zerbrechen (angenommen dass pro Client höchstens ein paar kurze Strings pro Sekunde kommen). Wahrscheinlich wird eher die Datenbank der Flaschenhals werden.

    Ach ja, um mal http://support.microsoft.com/?scid=kb%3Ben-us%3B111855&x=6&y=12 zu zitieren:

    The maximum number of sockets that a Windows Sockets application can use is determined at compile time by the manifest constant FD_SETSIZE. To do this, [...]

    Wie ernst man das nehmen kann, weiß ich nicht, da die Aussage sowieso schon Unfug ist. Die Maximalzahl Sockets in einem Programm hat rein gar nichts mit FD_SETSIZE zu tun.



  • hi

    es waere mal interessant zu wissen, ob die 2000 clients alle mit dem server verbunden bleiben oder ob er 2000 clients hat die sich nur dann verbinden, wenn sie paar zeichen rueber senden wollen.

    ein kleiner ueberblick was performance angeht:
    http://technixlab.de/net_performance.jpg

    ob die datenbank ein flaschenhals ist oder nicht kann man bis dato nicht beurteilen.

    meep meep



  • Hallo Leute,

    also 2000 Clients senden alle 30 sec. einen String.
    So läuft es ungefähr ab:

    Client meldet sich Verbindung herstellen
    Sendet String Daten empfangen
    Client geht (weis aber nicht ob er selber die Verbindung trennt)

    Die müssen nicht dauerhaft verbunden sein nur dan wen ein string empfangen werden soll. Kann aber auch vorkommen das sich mehrer Clients gleichzeitig melden.



  • in diesem fall wuerde ich einen server mit hausnummer 50 threads machen. die 50 nehmen verbindungen an, empfangen den string, werfen den in eine queue und beenden die verbindung. wenn mal mehr als 50 clients zur gleichen zeit connecten wollen, dann kommt der rest in eine warteschlange. sollte aber ruck zuck gehen.
    kannst dann ja mit der anzahl der threads rumspielen bis du einen halbwegs optimalen wert gefunden hast. es gibt aber keine veranlassung 2000 threads dafuer aufzubauen 🙂

    ein einzelner thread schiebt dann die daten aus der queue in die datenbank

    meep meep



  • Hallo Meep Meep,

    Das heist es könnten zu gleicher Zeit 50 clients gleichzeitig Connecten. Die senden die Message wird sofort in eine queue geschoben und thread geschlossen.

    und eine Andere Funktion schreibt den Queue Inhalt in die Datenbank.

    Richtig?



  • Memoo schrieb:

    Hallo Meep Meep,

    Das heist es könnten zu gleicher Zeit 50 clients gleichzeitig Connecten. Die senden die Message wird sofort in eine queue geschoben und thread geschlossen.

    und eine Andere Funktion schreibt den Queue Inhalt in die Datenbank.

    Richtig?

    ein anderer thread schreibt den inhalt in die DB.
    der thread wird nicht geschlossen, sondern die verbindung zum client.
    ansonsten ja

    Meep Meep



  • Wenn es richtig performant werden soll (für Windows): Thread-Pools und IO-Completion Ports. Ob das im Gegensatz zu Linux performant ist? Eher nicht.

    Wie kommst du zu dem Fazit "Eher nicht."?

    Gemessen oder einfach mal so daher geraten?



  • Mich wundert das ich hier bisher nichts von boost.asio gelesen habe wo das doch sonst immer gleich gerne genannt wird. Und grade für das was der OP machen möchte ist es doch gedacht.
    Und das sogar noch recht einfach da asio sich um die ganzen OS spezifischen Feinheiten kümmert.

    BR



  • <a href= schrieb:

    http://www.fefe.de/scalable-networking.pdf">
    Auch Microsoft hat das Problem, daß sie skalierbare Netzwerkprogrammierung
    anbieten wollen. Die Microsoft-Lösung hierbei ist, daß man einen Thread
    Pool aufmacht, und dann in jedem Thread mit einem SIGIO-ähnlichen Verfahren
    die Events benachrichtigt bekommt.
    Hier werden also die Nachteile von Threads mit den Nachteilen von SIGIO
    verbunden. Es ist beeindruckend, was Microsofts Marketing-Maschine aus diesem
    Schrumpelküken für ein Monster aufgeblasen hat.
    Immerhin gibt es da auch lustige Zitate in der Dokumentation:

    "First of all,
    threads are system resources that are neither unlimited nor cheap." Äh, nicht
    cheap? Ich dachte, das sei ihre Existenzberechtigung!



  • Kann mal einer Bitte das mit dem Boost näher erläutern?



  • Memoo schrieb:

    Kann mal einer Bitte das mit dem Boost näher erläutern?

    Da gibts nichts zu erläutern:
    Boost.Asio ist eine Library für Netzwerk und Serielle Kommunikation, welche OS Spezifische Dinge abstrahiert.

    Simon


Anmelden zum Antworten