Hallo, ich sehe mir gerade dieses Beispiel zum Erstellen von Server und Client per TCP an: http://www.c-worker.ch/tuts/wstut_op.php Anstatt nach erfolgter Verbindung einen neuen thread zu starten, der diesen bedient, möchte ich es bei nur einem einzigen belassen. Somit kann auch nur ein Client mit meinem Server gleichzeitig verbunden sein. Bei TCP ist die Verbindung fest geregelt. Bei UDP ist es aber so, dass jeder den Server "anschreiben" kann. Wie ist es dann aber bei Antworten VOM Server? Wird die Antwort dann an die IP geschickt, die die Verbindung zuerst aufgenommen hat?
> [..] UDP [..] Wie ist es dann aber bei Antworten VOM Server? Wird die > Antwort dann an die IP geschickt, die die Verbindung zuerst aufgenommen > hat? Nein, natürlich nicht. Die Antwort geht an die Adresse, die Du angibst.
brechbunkt schrieb: > Bei UDP ist es aber so, dass > jeder den Server "anschreiben" kann. Wie ist es dann aber bei Antworten > VOM Server? Wird die Antwort dann an die IP geschickt, die die > Verbindung zuerst aufgenommen hat? Bei UDP gibt es keinen Zustand, den man "Verbindung" nennen könnte. Es werden Pakete (bei UDP "Datagramm" genannt), versendet, die entweder ankommen oder auch nicht. Da steht die Quelladresse drinnen. Wenn der Empfänger mag, kann er diese auslesen und eine Antwort senden ...
Danke für die Antworten. Frank Esselbach schrieb: > Es werden Pakete versendet, die werden entweder ankommen > oder auch nicht. Da steht die Quelladresse drinnen. > Wenn der Empfänger mag, kann er diese auslesen und > eine Antwort senden ... Heißt das dann also, der erste Client der gesendet hat (somit seine Quelladresse bekannt ist) und dessen Nachricht der Server als erstes entgegen genommen hat, der bekommt dann immer die Antworten vom Server zurück? (In meinem Fall kann nur ein Client bedient werden, da nur ein thread) Ich habe das oben genannte Beispiel nun mit UDP umgesetzt. Während der Programmierung hatte ich immer per loopback getestet. Da war es verständlich, dass ich immer das richtig sende und empfange. Nun habe ich die Verbindung von meinem Linux-Rechnter aus ("nc [ip] [port]") am Windows-Server eröffnet und ohne am Windows die IP zu nennen kam die Antwort richtig zum Linux zurück. Zufall oder normal?
brechbunkt schrieb: > Heißt das dann also, der erste Client der gesendet hat (somit seine > Quelladresse bekannt ist) und dessen Nachricht der Server als erstes > entgegen genommen hat, der bekommt dann immer die Antworten vom Server > zurück? Nein. <seufz> Wenn dein Server den UDP-Socket erzeugt hat, dann hast du im folgenden zwei Möglichkeiten: 1. du rufst anschließend auf dem Socket connect() auf. Einer der Parameter von connect() ist die Zieladresse. Anschließend kannst du mit send() über den Socket Daten verschicken, die an diese Adresse gehen. 2. du rufst connect() nicht auf. Dann darfst du im folgenden auch nicht send() verwenden. Aber du kannst mit sendto() auf den Socket schreiben, wobei einer der Parameter für sendto() die Zieladresse ist. sendto() ist übrigens auch im ersten Fall erlaubt. Damit kannst du Pakete "außer der Reihe" an eine andere Adresse schicken als die die du vorher mit connect() festgelegt hast. Wie du das logisch handelst, bleibt vollkommen dir überlassen. Eine mögliche (und logische) Variante wäre, daß dein Server mit recvfrom() auf ein eingehendes Paket wartet. Sobald eins kommt, hat er die Absendeadresse (die wird von recvfrom() zurückgegeben) und kann dann mit sendto() seine Antwort schicken. Anschließend wieder zurück zur Warteschleife. Alles obige gilt so zumindest für die Linux-Implementierung der Berkeley-Sockets. Wie kompatibel WinSock ist, weiß ich nicht. Interessiert mich auch nicht. Windows ist keine Zielplattform für mich. Noch ein Vorteil von Linux: Dokumentation. Das obige steht alles so in der Manpage zu udp(7)
Stell Dir UDP wie eine Postkarte vor. Jemand schickt eine Nachricht irgendwo hin und hofft, dass sie auch ankommt. Es gibt keine formelle Antwort. Es gibt keine Verbindung. Ich schicke Dir "Hallo, wie geht es Dir". Du schickst mir "Mir geht es gut", falls du dazu Lust hast und meine Frage erhalsten hast. Deine Postkarte unterscheidet sich technisch nicht von meiner. Der Postbote kann nicht erkennen, welche der Karten die Frage und welche die Antwort war, es sei denn, er liest die Texte und interpretiert sie intelligent. UDP ist aber weder intelligent, noch schaut es in die Nutzdaten hinein. Für UDP ist jede Nachricht einfach nur ein Datenpaket, dass von irgend jemandem irgend wohin gesendet wird. Nichtmal die Port-Nummern haben für das Protokoll irgendeine Bedeutung. Jedes Paket hat Sender-Adresse + Sender-Port sowie Empfänger-Adresse + Empfänger-Port Die Port Nummern sind für das Netzwerkprotokoll jedoch völlig bedeutungslos. Manche Programme senden etwas an Port X und erwarten die Antwort ebebnfalls auf Port X. Andere Programme hingegen handhaben das ganz anders, zum Beispiel DHCP.
brechbunkt schrieb: > Bei UDP ist es aber so, dass > jeder den Server "anschreiben" kann. Ja, es gibt keine Verbindung. > Wie ist es dann aber bei Antworten > VOM Server? Wo es keine Verbindung gibt, gibt es auch keine Antworten, sondern nur Fragen. Zu einem Frage-Antwortspiel kann es erst werden, wenn deine Programmlogik eines daraus macht, also selber eine logische Verbindung zwischen Fragen und Antworten schafft. > Wird die Antwort dann an die IP geschickt, die die > Verbindung zuerst aufgenommen hat? Die Antwort wird an die Adresse geschickt, die du angibst. Wenn das die ist, von der die zugehörige Frage kam, hast du in erster Näherung eine Art Verbindung geschaffen. Aber: ein zweiter Kommunikationspartner auf demselben Host bringt schon das Gebäude zum Einsturz. Um auf UDP sowas wie ein Verbindung aufzusetzen, genügt es also nicht, eine IP-Adresse als Verbindungmerkmal zu speichern. Zusätzlich muß der Port gespeichert werden. Das Problem ist nun, daß du den auf dem "Server" garnicht weisst, du kennst nur den Port, von dem die Frage gesendet wurde, das ist nicht notwendigerweise der Port, auf dem der Peer die Antwort erwartet. Deine Programmlogik muß also sowohl auf dem "Client" als auch auf dem "Server" eine (übereinstimmende) Logik enthalten, nach der bestimmt wird, auf welchem Port der Peer die Antwort auf die Frage erwarten wird. Im Übrigen gibt es bei UDP mit logischer Verbindung keinen "Client" oder "Server". Beide Peers sind eigentlich immer beides. Zum dedizierten Client oder Server werden sie auch erst wieder durch deine Programmlogik, die sich dementsprechend zwischen Client und Server unterscheiden muß. Einer muß auf Fragen warten und nur reden, wenn er welche gestellt bekommt, das ist dann der Server. Der Client hingegen muß aktiv werden, er muß die Fragen stellen und damit die Kommunikation anstoßen.
Tipp am Rande: Mancher zieht daraus den Schluss, dass UDP nur für Botschaften sinnvoll ist, die keine hin-und-her Kommunikation darstellen. Und kann ziemlich daneben liegen. Ich hatte schon Beispiele von Client/Server-Anwendungen, die mit TCP völlig auf die Nase fielen und UDP den weit sinnvolleren Weg dargestellt hätte. Nicht immer ist die Transportabsicherung von TCP hilfreich, insbesondere wenn auf anderen Layern der Kommunikation ebenfalls schon eine solche stattfindet.
Stefan us schrieb: > Nichtmal die Port-Nummern haben für das Protokoll irgendeine Bedeutung. Das stimmt so nicht. Die Portnummer ist Teil der Adresse. Ohne Portnummern könnte UDP nur genau einen Empfänger pro Computer haben und wäre recht nutzlos. Erst dadurch daß die Zieladresse eines UDP-Pakets eine Portnummer enthält, kann der IP-Netzwerkstack entscheiden, in welchen Socket er das Paket übergibt. Als Analogie nehme man die Hausnummer in einer Postadresse. Ohne Hausnummer kommt die Postkarte zwar in die richtige Stadt und in die richtige Straße. Aber erst mit einer Hausnummer kann der Postbote entscheiden in welchen Briefkasten er sie stecken muß (in diesem vereinfachten Modell gibt es an jedem Haus nur einen Briefkasten).
Nur am Rande: brechbunkt schrieb: > Anstatt nach erfolgter Verbindung einen neuen thread zu starten, der > diesen bedient, möchte ich es bei nur einem einzigen belassen. Somit > kann auch nur ein Client mit meinem Server gleichzeitig verbunden sein. Du kannst auch in einem Thread beliebig viele Verbindungen haben. Mit select() oder poll() kannst du auf Daten von mehreren gleichzeitig warten. Damit kommt man ziemlich weit, ohne sich mit Threads rumschlagen zu müssen. Die braucht man eigentlich erst, wenn man soviel Last hat, dass man sie auf mehrere Prozessorkerne verteilen muss oder wenn das Generieren einer Nachricht so viel Zeit brauchen kann, dass andere Verbindungen dann sehr lange blockiert wären.
Ja stimmt. Nur bestimtm die Anwendung selbst, auf welchen Ports sie lauschen möchte. Das Protokoll schreibt nicht vor, dass die Port Nummer einer Antwort mit der Portnummer einer Anfrage identisch sein muss.
Rolf Magnus schrieb: > brechbunkt schrieb: >> Anstatt nach erfolgter Verbindung einen neuen thread zu starten, der >> diesen bedient, möchte ich es bei nur einem einzigen belassen. Somit >> kann auch nur ein Client mit meinem Server gleichzeitig verbunden sein. > > Du kannst auch in einem Thread beliebig viele Verbindungen haben. Mit > select() oder poll() kannst du auf Daten von mehreren gleichzeitig > warten. Nur bringt das vergleichsweise wenig, wenn man einen UDP-Server baut. Denn der hat ja i.d.R. nur genau einen Socket. Im Gegensatz zu TCP, wo man den listen()ing Socket hat, auf dem man accept() macht, das dann für jede neue Verbindung einen neuen Socket ausspuckt. Bei UDP hat man hingegen nur den einen Socket. Und aus dem kann man Pakete auch nur sequentiell auslesen. So lange das Programm regelmäßig zum revcfrom() kommt, ist alles in Butter. Darüber hinaus hat der IP-Stack ja auch noch eine Warteschlange (queue) für eingehende Pakete.
Axel Schwenke schrieb: > Bei UDP hat man hingegen nur den einen Socket. Nicht zwangsläufig. Man kann über diesen einen Socket einen separaten Port für die Kommunikation aushandeln. Dann geht auch mehr parallel.
:
Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.