Wiederherstellen von IP / Port von Socket Descriptor
Frage
Ich schreibe ein Klon von inetd , in denen ich muss einen Server ausgeführt werden, der die IP und den Port des Client daran anschließen druckt.
Wie ich überschreiben STDIN
und STDOUT
mit dem Socket-Deskriptor, meine erste Lösung , dies zu tun war, die sockaddr_in
Struktur zu erholen, die die benötigten Informationen enthält. Dadurch mit getsockname()
wird jedoch eine leere Struktur zurückkehrt, wobei alle Bits auf 0 gesetzt.
Jede Idee von dem, was mit meinem Ansatz ist falsch? Gibt es andere Ansätze, die ich verwenden kann, um die IP / Port?
erholenDanke
Lösung
Als R .. wies darauf hin, sollten Sie getpeername
. Sowohl die Funktion und getsockname
nimmt einen Dateideskriptor als erstes Argument, keinen Strom Zeiger (FILE *
). Verwenden fileno(stdin)
den Dateideskriptor für die Standardeingabe zu erhalten (oder schwer Code es STDIN_FILENO
, wie es Konstante).
Auch das letzte Argument zu getsockname
und getpeername
sollte ein Zeiger auf socklen_t
sein, nicht eine Konstante ist, und Sie sollten eine sockaddr_in
für TCP / IP verwenden:
struct sockaddr_in peeraddr;
socklen_t peeraddrlen = sizeof(peeraddr);
getpeername(STDIN_FILENO, &peeraddr, &peeraddrlen);
Sehen Sie ein komplettes Beispiel hier .
Andere Tipps
Mit getpeername
. Ich vermute, dass das Problem, dass getsockname
ist, die Informationen für die eigene (lokale) Seite des Sockels zurückkehrt, die wahrscheinlich auf 0.0.0.0 gebunden ist (dh es Verbindungen von jeder Schnittstelle annehmen kann).
Edit: Ich glaube, ich Ihr tatsächlicher Fehler gefunden, den Code zu lesen. Diese Zeile ist falsch:
getsockname(stdin, &addr, sizeof(addr));
Die getsockname
und getpeername
Funktionen übernehmen eine socklen_t *
(a Zeiger ) als drittes Argument, kein size_t
. Der Compiler sollten Sie diesen Fehler erzählen, wenn Sie einen Header mit dem Prototyp für getsockname
nicht mit einberechnet. Auch, wie bereits gesagt wurde, stdin
falsch ist. Versuchen Sie:
socklen_t len = sizeof addr;
getpeername(0, &addr, &len);
oder (C99 only):
getpeername(0, &addr, (socklen_t[1]){sizeof addr});
Sie sollten auch den Rückgabewert werden überprüft; Wenn ja, würden Sie sehen, dass es Fehler ist zurück.
Wenn Sie diese Informationen für den Remote-Client benötigen, müssen Sie rufen Sie getpeername () .