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

Était-ce utile?

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);

Voir un exemple complet .

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 () .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top