A3 - Ergebnis zurücksenden

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

A3 - Ergebnis zurücksenden
Hi,

wenn ich in meinem MultiplyServerSkeleton das Ergebnis habe, woher weiß ich dann, wohin ich es zurücksenden muss?
Dem Client kann man die Server-Adresse und das Port ja per Kommandozeile geben, aber dem Server die Client-Adressdaten per Kommandozeile zu geben ist wenig sinnvoll, da der Server ja mehrere Clients bedienen soll.
Gebt Ihr die Adresse des Clients dem Server verpackt mit message-ID und Parametern in der Message?


Dem Communication-Object gibts du beim receive einen Pointer auf ein Address-Object, das mit der Quell-Adresse gefüllt werden sollte (Aufgabe 2). An diese Quell-Adresse kannst du die Antwort schicken. Dein Client muss dann natürlich auf derselben Adresse auf Antworten horchen von der er auch abschickt.


Also bei mir ist das anders:

Client:

Bekommt die Server-Adresse via Kommandozeile
Sendet dort Parameter hin und horcht auf Antwort von dieser Adresse.
Z.B. (Kommandozeileneingabe):
a3 client faui05a@informatik.uni-erlangen.de 4711

Server:

horcht auf Anfragen von 127.0.0.1
a3 server 4711

Könntest du mir ein paar Zeilen code geben, wie du das machen würdest?


Im Prinzip ist das ganz einfach:

Der Server horcht auf einem vordefinierten Port (z.B. 8000) auf Anfragen von beliebiegen IP-Adressen. Wenn er eine Anfrage bekommt, dann bearbeitet er diese, und schickt die Antwort an den Absender der Nachricht zurueck (den Absender kriegst du aus dem recvfrom-Aufruf).

Der Client schickt die Anfrage an den Server. IP und port des Servers kriegt er wie du gesagt hast von der Kommandozeile. Allerdings musst du vor dem Senden den Socket, mit dem du die Nachricht abschickst per bind() an einen Port binden. Und genau an diesen Port wird der Server die Antwort dann schicken, d.h. dort muss dann auch der Client horchen. Wenn du Client und Server auf demselben Rechner ausfuehren willst, musst du natuerlich auf dem Client einen anderen Port nehmen (z.B. 7000), den logischerweise koennen auf einem Rechner nicht zwei Prozesse gleichzeitig auf denselbem Port horchen.
Das ist vielleicht auch das Problem das du in dem anderen Posting ( [VS] - A3: Client empfängt, was er gesendet hat) beschrieben hast. D.h. dein Server kann die Nachricht gar nicht empfangen weil der Server schon den Socket mit demselben Port aufgemacht hat. Ueberpruef mal die Rueckgabewerte von den diversen Socket-Funktionen und schau ob die alle erfolgreicht sind.


Auf der man-page von recvfrom steht:

ssize_t recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);

If from is not NULL, and the underlying protocol provides the source address, this source address is filled
in. The argument fromlen is a value-result parameter, initialized to the size of the buffer associated with
from, and modified on return to indicate the actual size of the address stored there.

Ist da die Absender-Addresse drinnen? Wie kriege ich diese Adresse in ein char-array?

Muss ich 4 chars aus from.sin_addr kopieren, um die IP-Nummer zu bekommen?


das struct sockaddr * from ist in wirklichkeit (jedenfalls wenn du UDP benutzt) ein sockaddr_in *, d.h. du uebergibst dem recvfrom einfach ein struct sockaddr_in * (und fuer fromlen natuerlich sizeof(sockaddr_in)). Das kannst du dann fuer das sendto benutzen(natuerlich vorher in einem Adress-Objekt verkapselt, blah blah…)

Das steht so uebrigens auch in den Uebungs-Folien drin, oder auch in den diversen Socket-Tutorials im Netz.