Récupération Port / IP Socket Descriptor
Question
J'écris un clone de inetd dans lequel Je dois lancer un serveur qui imprime l'adresse IP et le port du client qui se connecte à lui.
Comme je l'ai Ecraser STDIN
et STDOUT
avec le descripteur de socket, ma solution initiale pour ce faire était de récupérer la structure sockaddr_in
, qui contient les informations nécessaires. Faire cela avec getsockname()
, cependant, est de retour d'une structure vide, avec tous les bits à 0.
Toute idée de ce qui ne va pas avec mon approche? Y a-t-il d'autres approches que je peux utiliser pour récupérer l'IP / Port?
Merci
La solution
R .. a, vous devez utiliser getpeername
. Les deux cette fonction et getsockname
prendre un descripteur de fichier comme premier argument, et non pas un flux pointeur (FILE *
). Utilisez fileno(stdin)
pour obtenir le descripteur de fichier pour l'entrée standard (ou coder en dur à STDIN_FILENO
, comme il est constant).
En outre, le dernier argument de getsockname
et getpeername
doit être un pointeur vers socklen_t
, pas une constante, et vous devez utiliser un sockaddr_in
pour TCP / IP:
struct sockaddr_in peeraddr;
socklen_t peeraddrlen = sizeof(peeraddr);
getpeername(STDIN_FILENO, &peeraddr, &peeraddrlen);
Autres conseils
Utilisez getpeername
. Je soupçonne que votre problème est que getsockname
retourne les informations pour votre propre côté (local) de la prise, ce qui est probablement lié à 0.0.0.0 (ce qui signifie qu'il peut accepter les connexions à partir de toute interface).
Modifier Je pense avoir trouvé votre bug réelle lecture du code. Cette ligne est erroné:
getsockname(stdin, &addr, sizeof(addr));
Les getsockname
et les fonctions getpeername
prennent socklen_t *
( pointeur ) comme troisième argument, pas size_t
. Le compilateur devrait être vous dire au sujet de cette erreur, sauf si vous avez oublié d'inclure un en-tête avec le prototype de getsockname
. De plus, comme cela a déjà été dit, stdin
est incorrect. Essayez:
socklen_t len = sizeof addr;
getpeername(0, &addr, &len);
ou (C99 uniquement):
getpeername(0, &addr, (socklen_t[1]){sizeof addr});
Vous devriez aussi vérifier la valeur de retour; si vous avez fait, vous verriez qu'il est des erreurs de retour.
Si vous avez besoin les informations pour le client distant, vous devez appeler getpeername () .