Netzwerk Client-Server Modell Problem



  • Also eine Broadcast aufnehmen und auswerten braucht auch Resourcen. Da ist es besser du macht eine Thread bzw. AsyncSockets.



  • Der Client könnte laufend UDP Pakete an den Server schicken, der Server antwortet sobald er online ist.

    Oder der Server schickt UDP Pakete an die Clients, allerdings müsste er dazu die IPs aller Clients kennen, oder die Clients und der Server müssten im gleichen Netzwerksegment sein.

    Das "nicht sicher" bei UDP kann man dadurch umgehen dass man einfach alle paar Sekunden Pakete schickt - irgendwann geht schon eines durch.

    Der Verbindungsaufbau bei TCP ist normalerweise auch nicht wirklich so "sicher", da AFAIK unter Windows nur 3x (oder 5x?) ein ACK geschickt wird -- wenn alle 3 (5) verloren gehen schlägt der Verbindungsaufbau auch fehl.



  • Tobias W schrieb:

    Naja, das Problem ist das dieser Client so Ressourcensparend wie möglich implementiert werden muss, und dann ist die Aufteilung in mehrere Threads nicht zu bevorzugen (Stichwort Threadwechsel, Mutexe/Semaphoren).

    Das halte ich für eine übertrieben kritische Darstellung. Thread-Wechsel sind im Gegensatz zu Prozesswechseln sehr ressourcen-schonend. Im Prinzip wird nur der Stackpointer geändert. Mutexe und Semaphoren sind ebenfalls nicht besonders teuer, wenn man sie richtig benutzt. In Deinem Fall ist ja kaum Synchronisation nötig. Eigentlich erst in dem Moment, wo anschließend eh eine Verbindung aufgebaut werden muß. Das kostet dann sowieso Zeit.



  • @Unix-Tom:
    In wie weit braucht das aufnehmen eines Broadcasts mehr Ressourcen beim Empfänger? Kannst du mir das erklären, oder mir einen Tipp geben wo ich solche Infos finden kann? Danke!

    @hustbaer:
    Ich schätze anstatt laufend UDP Pakete zu senden wäre ein Thread der hin und wieder probiert die Connection aufzubauen sinnvoller. Ist zwar auch eine Art des Pollings, aber mir einfach sympathischer 🙂

    Und zum Server -> dieser hat keine Informationen darüber, wieviele Clients existieren.

    Und das TCP auch nicht so sicher ist sei mal dahingestellt. Die Chance auf Fehler bei TCP ist doch wesentilch geringer als bei einer Datagrammübertragung (per UDP).

    @Jester:
    Ich finde das nicht so übertrieben, denn die Daten aus dem Netzwerkthread müssen ja auch irgendwie geschützt an den anderen Thread weitergegeben werden. Und der Client läuft auf keinem PC im herkömmlichen Sinn, sondern auf einem Board der einen schon stark ausgelastetem PowerPC mit abgespecktem Linux hat. Der ist mit den aktuellen Arbeiten auch schon zu 60% beschäftigt...

    Also ich sehe es wird mir wohl nichts anderes übrig bleiben als einen Thread für die Netzwerkaufgaben abzustellen...

    Ach und danke für die vielen schnellen Antworten 👍



  • Tobias W schrieb:

    Ich finde das nicht so übertrieben, denn die Daten aus dem Netzwerkthread müssen ja auch irgendwie geschützt an den anderen Thread weitergegeben werden.

    Moment mal, wir sprechen doch davon zu überprüfen, ob ein verbindungsaufbau möglich ist? Welche Daten müssen denn da weitergereicht werden? Abgesehen davon genügt zur weitergabe der daten doch ein pointer auf die Daten, oder? Für die Freigabe ist dann der Benutzer verantwortlich. Schließlich kann nur der wissen, wann er damit fertig ist.



  • Und das TCP auch nicht so sicher ist sei mal dahingestellt. Die Chance auf Fehler bei TCP ist doch wesentilch geringer als bei einer Datagrammübertragung (per UDP).

    Wenn du 5 UDP Pakete schickst (im Abstand von vielleicht 1 Sekunde, also nicht zu schnell) ist die Wahrscheinlichkeit dass wenigstens eines davon ankommt grösser als die Wahrscheinlichkeit dass der Aufbau einer TCP/IP Verbindung hinhaut. So war das zu verstehen.



  • @Jester:
    Also ich hab nicht genau erzählt was genau gemacht wird. Einen Benutzer im herkömmlichen Sinne gibts nicht. Weder Client noch Server werden von einem Menschen bedient. Es können Daten vom Host kommen die der Client im ersten Thread verarbeiten muss und anders rum. Und um keinen gegenseitigen Ausschluss zu erzeugen wenn diese Daten vom anderen Thread auslesen, benötige ich z.B. ein Mutex.
    Und das Problem hätte ich eben mit einem Thread nicht.

    Aber ich sehe schon: alles andere als den Client in 2 Threads zu teilen wäre Frickelwerk...

    @hustbaer:
    Naja, ich glaub dir das jetzt mal gerne, ich hab mich nämlich damit nie beschäftigt wie hoch die Wahrscheinlichkeiten von solchen Dingen sind. Aber danke für den Hinweis. Ich hätte mich jetzt auf die "Sicherheit" von TCP verlassen. Tja, bin halt ein naiver Mensch 🙄



  • Tobias W schrieb:

    @Jester:
    Also ich hab nicht genau erzählt was genau gemacht wird. Einen Benutzer im herkömmlichen Sinne gibts nicht. Weder Client noch Server werden von einem Menschen bedient.

    Äh ja. Hast Du jemals als Benutzer in diesem Sinne Speicher freigegeben? -- Ne? Genau: Mit Benutzer ist hier natürlich derjenige gemeint, der den restlichen Client-Code programmiert. Und das Netzwerkmodul als Bibliothek verwendet. (Bitte komm mir jetzt nicht mit "ich programmiere das aber alleine")

    Und um keinen gegenseitigen Ausschluss zu erzeugen wenn diese Daten vom anderen Thread auslesen, benötige ich z.B. ein Mutex.
    Und das Problem hätte ich eben mit einem Thread nicht.

    Naja, im Prinzip mußt du ja nur nen pointer übertragen. Da nur einer schreibt ist das garnicht sooo kritisch... evtl kann man, wenn's geschickt gemacht ist, da um ne komplette synchronisation mit nem mutex rumkommen.

    Abgesehen davon ist das selten das Problem -- wenn es gut gemacht ist. 🙂



  • evtl kann man, wenn's geschickt gemacht ist, da um ne komplette synchronisation mit nem mutex rumkommen.

    Nur wenn man Lust hat selbst mit Barriers zu arbeiten, oder sich auf plattformspezifische Eigenheiten zu verlassen 😉
    Ich würde einfach ne Mutex nehmen, und dann mal gucken ob's ein Problem gibt vonwegen langsam (was ich nicht erwarte).



  • hustbaer schrieb:

    Nur wenn man Lust hat selbst mit Barriers zu arbeiten, oder sich auf plattformspezifische Eigenheiten zu verlassen 😉

    Dadurch, dass die Kommunikation nur in eine Richtung geht muß man das vermutlich nichtmal... aber wie auch immer. Auch mit Mutex dürfte die performance kein problem sein.



  • Klar, der Client wird als Bibliothek von anderen verwendet. Aber ich möchte mich nicht drauf verlassen das es bei geschickter Pointerübergabe problemlos laufen könnte.

    Wenn das mal ausgeliefert wird und nach einigen Monaten lässt diese Stelle ein Modul aufhängen, will ich nicht in der nähe meines Cheffe sein 😃

    Mal im ernst, ich denke ich schreib mir einen kleinen Prototypen mit dem ich die Last mal simulieren kann, dann werd ich weiter sehen. Eventuell seh ich das ganze Performancetechnisch zu eng.



  • Tobias W schrieb:

    Klar, der Client wird als Bibliothek von anderen verwendet. Aber ich möchte mich nicht drauf verlassen das es bei geschickter Pointerübergabe problemlos laufen könnte.

    Ich weiß nicht, von welchen Frickelqualitäten Du bei mir ausgehst, aber wenn ich meine, dass das funktioniert wenn man es geschickt macht, dann meine ich, dass man es auf bibliothekseite geschickt machen muß, nicht dass es eventuell funktioniert, wenn der (bibliotheks-)client geschickt arbeitet.

    Ein Lasttest klingt wirklich vernünftig. Ich tippe, dass die Synchronisation kein Problem sein wird. Lass mal was von Dir hören, wenn Du mehr weißt!



  • Lass mal was von Dir hören, wenn Du mehr weißt!

    Werd ich machen. Außerdem muss ich mich eindeutig tiefer in das Thema Threads einlesen.



  • Jester schrieb:

    hustbaer schrieb:

    Nur wenn man Lust hat selbst mit Barriers zu arbeiten, oder sich auf plattformspezifische Eigenheiten zu verlassen 😉

    Dadurch, dass die Kommunikation nur in eine Richtung geht muß man das vermutlich nichtmal... aber wie auch immer. Auch mit Mutex dürfte die performance kein problem sein.

    Wenn man nur einen Zeiger austauscht müsste man das Schreiben des Zeigers "mit release" sein und das Lesen des Zeigers "mit acquire".
    Dafür braucht man je nach Plattform ne CPU memory barrier, und auf jeden Fall ne Compiler Barrier.

    Da man dabei so enorm viel übersehen und ganz allgemein falsch machen kann würde ich auf jeden Fall erstmal mit einer Mutex anfangen.



  • Tobias W schrieb:

    @Unix-Tom:
    In wie weit braucht das aufnehmen eines Broadcasts mehr Ressourcen beim Empfänger? Kannst du mir das erklären, oder mir einen Tipp geben wo ich solche Infos finden kann? Danke!

    Ob er nun wartet das ein UDP und diesen dann auswertet (könnte ja auch ein anderes Programm verursachen) kommt oder ob er versucht eine Verbindung zum Server aufzubauen spielt da keine Rolle. Beides braucht CPU-Leistung.
    Er sagte das er es deshalb nicht machen möchte weil er Ressourcen sparen will und kein Threads möchte.
    Code braucht er sowieso. Der Client lauscht oder er sendet.



  • So, nur so zur Info:

    Ein Lasttest hat ergeben, dass die Performance mit 2 Threads kein Problem sein sollte. Auch Mutexe zur synchronisation bringen die Last nicht annähernd so hoch wie ich befürchtet habe.

    Das heißt ich werde, auch wenn die Kommunikation nur in eine Richtung geht, Mutexe verwenden um sicher zu stellen das nichts schief geht.

    Nochmal vielen Dank für die vielen hilfreichen Antworten...


Anmelden zum Antworten