Seite 1 von 1

Spezielles Client/Server-Szenario: Fragen zur Vorgehensweise

Verfasst: 22. Januar 2010 22:18
von oberschlingel
Hallo,

ich muss zum ersten Mal eine Client-/Serveranwendung programmieren und habe ein paar ganz grundsätzliche Fragen, die ich mit Hilfe des Forums, der Doku und dem Fortune-Beispielen beantworten konnte. Ich bitte mein Unwissen im Netzwerkbereich zu entschuldigen.

Ich wäre euch über Ratschläge sehr dankbar!

Szenario:
Bis zu 50 Clients in einem lokalen Netzwerk verbinden sich mit der Serveranwendung. Benutzer arbeiten dann an den Clients. Jeder Client ist an sich so auch schon recht ausgelastet. Während der Arbeit soll jeder Client nun in regelmäßigen Abständen (z.B. alle 5 Sekunden) einen Status an den Server übermitteln. Gleichzeitig soll der Client auch auf Nachrichten vom Server reagieren können.

Die Serveranwendung listet alle verbundenen Clients und deren Status in einer GUI auf. Der Status wird regelmäßig aktualisiert, wenn die Clients einen neuen Status übermitteln. Zusätzlich soll der Benutzer der Serveranwendung Textnachrichten an alle oder individuelle Clients versenden können.

Wenn ich mir das Fortune-Server-Beispiel ansehe, sendet der Server nur "Antworten" an die Clients. Also immer nur, nachdem eine Nachricht vom Client eingegangen ist. Das ist für einen Teil meiner Anforderungen genau richtig (Status aktualisieren), beim anderen Teil (zusätzlich Textnachrichten an Clients) blicke ich aber noch nicht ganz durch.

Somit ergeben sich für mich folgende Fragen:


Allgemein:
1. TCP- oder UDP-Protokoll verwenden?
2. Ist der Server ein "echter" Server, wenn er auch auf eigenen Wunsch Nachrichten an Clients versendet? Oder sind die Clients dann auch "Server"?
3. Die Verbindungen nach Aufbau halten oder für jede Nachricht eine neue Verbindung und danach wieder beenden?

Server:
4. Einen Thread für jede neue Verbindung erzeugen oder den Server ohne Threads realisieren? (bis 50 Clients, gehaltene oder jedes Mal neue Verbindung - siehe Frage 2, GUI)
5. Um auf Benutzerwunsch (z.B. über Button) eine Nachricht vom Server an einen/mehrere Clients zu senden: QTcpServer auch bei Clients notwendig? Oder muss ich zwei TcpSockets erzeugen (senden/empfangen)? Oder unterbreche ich die Warte-auf-Daten-vom-Client-Schleife einer gehaltenen Verbindung, um zwischendrin über den Socket eine Nachricht zu versenden?

Client:
6. Sollte für die Clientfunktionalität ebenfalls ein Thread erzeugt werden? Ich denke bei einer vom Server gehaltenen Verbindung, bei der auch Nachrichten empfangen werden müssen macht ein Thread Sinn oder? Zudem muss ja regelmäßig der Status versendet werden und die GUI ist währenddessen auch schon anderweitig sehr beschäftigt.

VIELEN DANK FÜR EURE TIPPS!

Verfasst: 25. Januar 2010 12:16
von RHBaum
ich muss zum ersten Mal eine Client-/Serveranwendung programmieren
Mein Beileid :lol: neee im ernst, so schlimm isses ned, es gibt zwar ne Menge zu beachten und es ist vieles neu, aber es macht auch Spass !

Ich versuch mal die Fragen zu beantworten:
1. TCP- oder UDP-Protokoll verwenden?
zu 99% würd ich sagen, iss TCP das geeignetere Protokoll bei dir.
TCP iss statusbehaftet, das heisst du baust ne Verbindung auf, die verbindung hat den Status connected oder eben nicht. Weiterhin stellt dir TCP sicher, dass alle deine daten in der richtigen reihenfolge und überhaupt beim client oder server ankommen, ansonsten gibts fehler. Das macht vieles einfacher.

UDP: du schickst daten ins blaue an eine IP Adresse. Ob die ankommen oder nicht, kriegst du nicht mit, sondern musst du selber implementieren, in dem dein Empfaenger entsprechende antworten schickt. Sprich du muesstest die flusskontrolle selber programmieren -> aufwendig.
TCP iss mehr overhead aber einfacher, UDP iss ohne overhaed, aber komplizierter. meist nimmt man heutzutage UDP nur wenn das Protokoll tolerant gegenueber fehlenden packeten ist (zum bsp. positionsdaten bei spielen, wenn die statt 10 mal pro sekunde nur neinmal kommen, wird halt das eine mal interpoliert) oder wenn mandurch eigene besonderheiten die flusskontrolle effektiver implementieren kann als wie es das generische tcp macht (performance).
2. Ist der Server ein "echter" Server, wenn er auch auf eigenen Wunsch Nachrichten an Clients versendet? Oder sind die Clients dann auch "Server"?
Wer welche packete im laufenden betrieb initiert, is fuer die Server client unterscheidung irrelevant.
Auf TCP Ebene ist derjenige der Server, der eine grosse zeitspanne auf Anfragen wartet (Sockets bind) und dabei auf alles horcht was an einem oder mehreren interfaces eintrifft, und dann die verbindung zulaesst, waehrend der client derjenige ist, der sich mit gezielt mit einer bestimmten IP verbindet (connected) und scho nach paar sek nen timeout bringt, wenn der server ned reagiert.
Iss der verbindungsaufbau vorbei, issi vollkommen wurscht, wer anfangt zu kommunzieren und auf antworten wartet fuer die rollenverteilung.

Bei UDP gibts sowas ned. Da spricht man zwar auch oft von server und clients, aber das wird komplett ueberhalb vom UDP protokoll abgebildet, also waer teil der applikation.

Oft koennen auch mehrere ebenen eigene Definitionen schaffen. z.b. wenn 2 rechner mehrere tcp verbindungen zueinander halten. So kann auf einer ebene der eine server der andere client, und auf anderer ebene es umgekehrt sein koennen.
Oder Proxies. gegenueber dem Orginalserver sind sie clients, und gegenueber dem orginalclient sind sie server :-)
3. Die Verbindungen nach Aufbau halten oder für jede Nachricht eine neue Verbindung und danach wieder beenden?
bei TCP iss fast halten der bessere weg. Verbindung aufbauen kosstet ressourcen (handschaking). Halten kostet nix. Ausser das eben der port die ganze zeit belegt ist .... aber normal iss das kein problem.
Bei UDP gibts sowas eh ned.
4. Einen Thread für jede neue Verbindung erzeugen oder den Server ohne Threads realisieren? (bis 50 Clients, gehaltene oder jedes Mal neue Verbindung - siehe Frage 2, GUI)
selectiver server vs paralleler.
Prinzipiell, hat dein server mehrere Kerne, nimmst soweiso multithreading ! wenn ned gar multiprocessing.
selectiver server iss eher fuer einfachere aufgaben, wenn es auf die antwortzeiten ned so ankommt, und multithreading / multiprozessing allgemein probleme macht. Auf singlecore rechner kann nen slectiver server geringfuegig schneller sein, weil multithreading overhaed erzeugt da. Aber wer hat heut noch single cores ?
Ich find auch das sich parallele server angenehmer zu programmieren lassen, ich mag das select ned so .... iss aber auch persoenliche vorliebe.
Und multithreading iss eh gut, wenn man es beherscht fuer andere anwendungsgebiete.
5. Um auf Benutzerwunsch (z.B. über Button) eine Nachricht vom Server an einen/mehrere Clients zu senden: QTcpServer auch bei Clients notwendig?
mit QSockets kenn ich mich ned so aus, aber denk es ist gleich .
Normale BSD sockets sind bidirektional. Das heisst du kannst senden und empfangen. Also bei synchroner programmierung kannst du auf clientseite mit einem thread senden, und gleichzeit einen thread zum empfangen auf den socket schicken.
Beim server ebenfalls. ein thread behandelt die logikschicht und wenn was zu senden iss, holt er sich den entsprechenden socket fuer den client, und schickt die daten ab, waehrend auf jedem socket fuer jeden client nen thread hockt, der bei einkommenden daten die zur logicschicht durchreicht.
Ergo du kannst lesen und schreiben gleichzeitig (multithreaded) auf einen socket.

Bei QT brauchst wahrscheinlich ned mal die threads, weil die dinger eh assynchron sind, das heisst der thread im hintergrund fuer dich schon erstellt wird. Du musst nur noch auf events horchen.
6. Sollte für die Clientfunktionalität ebenfalls ein Thread erzeugt werden? Ich denke bei einer vom Server gehaltenen Verbindung, bei der auch Nachrichten empfangen werden müssen macht ein Thread Sinn oder? Zudem muss ja regelmäßig der Status versendet werden und die GUI ist währenddessen auch schon anderweitig sehr beschäftigt.
Siehe punkt 5. Also bei direkter Socketprogrammierung wuerd ich nen thread zum lesen nehmen, bei QT sockets wiederum wuerd ich auf die signale hoeren.

Ciao ...