Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

11.08.2014, 17:13

Server-Client-Implementierung mit UDP

Hi, ich habe in der Vergangenheit bisher mit TCP gearbeitet und wollte mich nun mal an UDP herantrauen.
  • Unicast und Broadcast: UDP arbeitet ja verbindungslos, d.h. ich brauche nur an einem Port zu lauschen um die entsprechenden Daten zu lesen. Wenn ich vom Client an den Server (dessen IP+Port dem Client bekannt sind) eine Nachricht schicke, weiß der Server folglich von welchem Client-Port diese kam und kann - sofern der Client dort auch lauscht - ihm antworten. Wie sieht das bei Broadcasts aus? Afaik habe ich eine (feste) Broadcast-Adresse und brauche einen (implementierungsabhängig gewählten) Port, der dann aber für alle Clients gleich ist. Nun müssten die Clients sowohl auf ihren bisherigen "Unicast-Port", als auch dem Broadcast-Port lauschen. Wie realisiere ich das: verwende ich zwei UDP-Sockets oder lasse ich den Client abwechselnd lauschen (d.h. erst alle Pakete vom Unicast-Port, dann auf Broadcast wechseln und alles lesen, danach wieder zurück etc.)?
  • Der Server kann sich ja sie IPs und Ports seiner Clients merken, indem er sie - wenn sie bisher noch "unbekannt" waren - lokal speichert. Ich frage mich gerade wie ich das am effizientesten tue. Bietet es sich an die IP-Port-Tupel in ein Set einzufügen? Ich habe bisher zwei assoziative Container (konkret: std::map) verwendet: der erste Container mit Key=ID und Value=Host+Port und den zweiten Container andersherum. So kann ich zu einer ClientID die IP+Port bekommen (wenn ich "an eine ID schicken will") und zu IP+Port die ID bekommen sofern vorhanden (z.B. um zu prüfen ob ich vom diesem Client schon etwas bekommen hatte).. oder löst man das ganze ganz anders?
  • Nochmal zum Broadcast und Unicast: Angenommen ich kenne am Server eine Menge von Clients, die ich über ein bestimmtes Event benachrichten will. Tendenziell würde ich zum Broadcast tendieren .. ist das die gängige Form?

LG Glocke

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

2

11.08.2014, 19:55

generell: Manchmal hilft es sich klar zu machen, dass es rein auf der UDP Ebene keinen Server bzw. Client in dem Sinne gibt.

zu 1: Ich verstehe das Problem noch nicht so ganz. Du kannst eigentlich mit einem UDP Socket sowohl Broadcast als auch direkt adressierte Pakete empfangen. Es stimmt, dass du für ein Broadcast üblicherweise einen Port festlegst. Über den kannst du aber alle Kommunikation laufen lassen. Du musst halt nur immer prüfen von wem das Paket gerade kam.
zu 2: Warum nimmst du nicht einfach IP+Port als ClientID?
zu 3: Broadcast sind halt fürs senden in ein "Subnet" interessant. Funktionieren aber nur in Netzen, in denen sie nicht rausgefiltert werden. Üblicherweise schickt man es an jeden Client einzeln und nicht als Broadcast, außer es sollen eh alle Client im gleichen Netz erhalten oder dir ist die Netzwerkbelastung egal+die Netzwerkinfrastuktur lässt es zu.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

3

11.08.2014, 20:13

generell: Manchmal hilft es sich klar zu machen, dass es rein auf der UDP Ebene keinen Server bzw. Client in dem Sinne gibt.
Genau. Und ich möchte drum herum Server und Client bauen und mit UDP kommunizieren lassen.

zu 1: Ich verstehe das Problem noch nicht so ganz. Du kannst eigentlich mit einem UDP Socket sowohl Broadcast als auch direkt adressierte Pakete empfangen. Es stimmt, dass du für ein Broadcast üblicherweise einen Port festlegst. Über den kannst du aber alle Kommunikation laufen lassen. Du musst halt nur immer prüfen von wem das Paket gerade kam.
Muss ich den UDP-Socket auf Empfängerseite nicht an einen bestimmten Port binden? Ich habe mich bisher an die API-Doku von SFML gehalten .. oder handelt es sich dabei nur um eine Einschränkung der UDP-Implementierung?

Zitat

Binding the socket to a port is necessary for being able to receive data on that port.
Quelle: sf::UdpSocket

zu 2: Warum nimmst du nicht einfach IP+Port als ClientID?
Keine Ahnung .. war vllt zu einfach :D

zu 3: Broadcast sind halt fürs senden in ein "Subnet" interessant. Funktionieren aber nur in Netzen, in denen sie nicht rausgefiltert werden. Üblicherweise schickt man es an jeden Client einzeln und nicht als Broadcast, außer es sollen eh alle Client im gleichen Netz erhalten oder dir ist die Netzwerkbelastung egal+die Netzwerkinfrastuktur lässt es zu.
Dann sollte ich, wenn Sender und Empfänger über das Internet kommunizieren, eher an jeden einzelnen Empfänger senden als zu broadcasten - verstehe ich das richtig?

Werbeanzeige