2010-01-20 3 views
4

Dans le code suivant, je souhaite extraire l'adresse IP du client connecté après avoir accepté une connexion entrante. Que dois-je faire après le accept() pour y parvenir?Extraire l'adresse IP de la connexion qui écoute et accepte la programmation de socket sous Linux en c

int sockfd, newsockfd, portno, clilen; 
portno = 8090; 
clilen = 0; 
pthread_t serverIn; 
struct sockaddr_in serv_addr, cli_addr; 
sockfd = socket(AF_INET, SOCK_STREAM, 0); 
if (sockfd < 0) 
{ 
    perror("ERROR opening socket"); 
} 
bzero((char *) & serv_addr, sizeof (serv_addr)); 
serv_addr.sin_family = AF_INET; 
serv_addr.sin_port = htons(portno); 
serv_addr.sin_addr.s_addr = INADDR_ANY; 
if (bind(sockfd, (struct sockaddr *) & serv_addr, sizeof (serv_addr)) < 0) 
{ 
    perror("ERROR on binding"); 
} 

listen(sockfd, 5); 
clilen = sizeof (cli_addr); 
newsockfd = accept(sockfd, (struct sockaddr *) & cli_addr, &clilen); 
+0

Vous l'avez déjà dans cli_addr, n'est-ce pas? – zneak

+0

@zneak J'ai besoin d'IP pour le client qui me connecte – SjB

+0

oui, c'est ce que 'accept()' vous donne dans 'cli_addr'! Vous avez seulement besoin de le formater - regardez les réponses ci-dessous. –

Répondre

1

Vous pouvez suivre cet exemple:

#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <stdio.h> 

{ 
    int s; 
    struct sockaddr_in peer; 
    int peer_len; 
    . 
    . 
    . 
     /* We must put the length in a variable.    */ 
    peer_len = sizeof(peer); 
     /* Ask getpeername to fill in peer's socket address. */ 
    if (getpeername(s, &peer, &peer_len) == -1) { 
     perror("getpeername() failed"); 
     return -1; 
    } 

     /* Print it. The IP address is often zero because  */ 
     /* sockets are seldom bound to a specific local  */ 
     /* interface.           */ 
    printf("Peer's IP address is: %s\n", inet_ntoa(peer.sin_addr)); 
    printf("Peer's port is: %d\n", (int) ntohs(peer.sin_port)); 
    . 
    . 
    . 
} 
11

Votre cli_addr contient déjà l'adresse IP et le port du client connecté après accept() retourne avec succès, dans le même format que votre variable serv_addr. Utilisez inet_ntop pour convertir l'adresse IP en chaîne.

+0

J'ai besoin d'IP pour le client qui se connecte à moi qui utilise getpeername() – SjB

+3

Hmm, vous êtes confus quelque part. accept() renvoie l'adresse IP du client et le port client dans son second argument. Vous ** n'avez pas besoin de ** pour appeler getpeername(), car cela vous donne les mêmes informations exactes. –

+2

Refusée. Je pense que la confusion provient du fait que sockaddr contient l'IP comme 4 octets, alors que l'OP en a besoin dans le texte. –

2

Je pense que getpeername() n'est pas nécessaire - l'adresse du client est déjà remplie dans cli_addr par l'appel accept().

Vous avez seulement besoin d'utiliser inet_ntop(), getnameinfo(), ou gethostbyaddr() pour imprimer ou obtenir plus d'informations.

1

L'API est décrite dans les pages de manuel. Vous pouvez soit les parcourir à partir de la console, en commençant par man socket et suivre les références à man getpeername ou utiliser Konqueror, qui le rend bien avec des liens, si vous demandez l'adresse #socket. Dans mon cas sur Kubuntu il était nécessaire d'installer le paquet manpages-dev.

Questions connexes