IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Connaitre son adresse ip publique


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    78
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 78
    Points : 41
    Points
    41
    Par défaut Connaitre son adresse ip publique
    Bonjour a tous,

    dans le cadre du developpement d'un jeu, j'ai besoin de recuperer mon adresse ip public (la meme qu'on obtient en faisant un /sbin/ifconfig ou un ipconfig sous windows par exemple)
    en gros c'est pour eviter d'obtenir un joli 127.0.0.1 si je fait un gethostbyname de localhost par exemple.

    comment puis-je faire?

    les seules informations que j'ai trouve sur le net se resument a faire un system("ipconfig") ou d'autre genre de goretudes.

    Si qq'un possede un moyen un peu plus officiel, un ioctl ou un petit appel genre inet_local_to_a ou je ne sais trop quoi.

    Merci d'avance pour l'aide que vous pourrez m'apporter.

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Ce que j'ai l'habitude de faire, c'est gethostname() suivi de gethostbyname(), qui ne m'a encore jamais retourné 127.0.0.1 (sous Windows, du moins).

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    78
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 78
    Points : 41
    Points
    41
    Par défaut
    struct sockaddr_in addr;
    char buffer[1024];
    struct hostent *host;

    gethostname(buffer, 1024);
    std::cout << buffer << std::endl;
    host = gethostbyname(buffer);
    memcpy((char *) &addr.sin_addr.s_addr, host->h_addr_list[0], host->h_length);
    std::cout << "addr " << inet_ntoa(addr.sin_addr) << std::endl;
    exit(0);

    cela me retourne malheureusement 127.0.0.1

    l'hostname retourne par gethostname est bien le bon hostname (heureusement d'ailleurs).

    mais la structure hostent retournee par gethostbyname ne contient que 127.0.0.1, a moins que je n'aille pas chercher l'info au bon endroit....

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    78
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 78
    Points : 41
    Points
    41
    Par défaut
    je viens de tester sous windows, et cela marche effectivement.

    comment cela se fait que le fonctionnement de gethostbyname ne soit pas le meme ?

    quelqu'un connait-il une maniere de regler ce probleme sous linux?

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Février 2006
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 86
    Points : 97
    Points
    97
    Par défaut
    salut,

    il existe une technique bien connue qui consiste a "connecter" un socket UDP sur une adresse externe, puis a faire un getsockname() pour recuperer le nom (l'adresse) du socket connecte.

    voici un exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
    #include <stdio.h>
    #include <unistd.h>
    #include <strings.h>
     
    #include <sys/socket.h>
    #include <netinet/in.h>
     
     
    int
    getaddr( in_addr_t *oaddr )
    {  
       struct sockaddr_in  sin;
       struct in_addr      inaddr;
       in_addr_t           addr;
       socklen_t           alen;
       int                 sd;
     
       inaddr.s_addr = htonl( 0xc6290004 /*198.41.0.4*/ );
       bcopy( &inaddr.s_addr, &sin.sin_addr.s_addr, sizeof( in_addr_t ) );
       sin.sin_family = AF_INET;
       sin.sin_port   = htons( 53 );  /* <- sans importance */
     
       sd = socket( PF_INET, SOCK_DGRAM, 17 /*IPPROTO_UDP*/ );
       if( sd < 0 )
          return -1;
     
       if( connect( sd, (struct sockaddr *)&sin, sizeof( struct sockaddr_in ) ) < 0 )
          return -1;
     
       alen = sizeof( struct sockaddr_in );
       if( getsockname( sd, (struct sockaddr *)&sin, &alen ) < 0 ) {
          (void)close( sd );
          return -1;
       }
     
       (void)close( sd );
     
       bcopy( &sin.sin_addr.s_addr, &addr, sizeof( in_addr_t ) );
       *oaddr = ntohl( addr );
     
       return 0;
    }
     
     
    int
    main( int argc, char *argv[] )
    {  
       in_addr_t  addr;
     
       if( getaddr( &addr ) < 0 )
          return -1;
     
       (void)printf(
          "%d.%d.%d.%d\n",
          ( addr >> 24 ) & 0xff, ( addr >> 16 ) & 0xff,
          ( addr >>  8 ) & 0xff, ( addr       ) & 0xff
       );
     
       return 0;
    }
    quelques commentaires:

    . l'adresse externe choisie ici (198.41.0.4) est celle d'un root server (DNS). ce n'est peut-etre pas le meilleur des choix possibles, mais l'important est d'etre sur qu'il s'agit bien d'une adresse routee par ton interface par defaut,

    . le connect() en UDP n'envoie rien sur le reseau, il ne faut donc pas s'attendre a voir passer quelque-chose. il s'agit simplement d'associer le socket a ta route par defaut,

    . les bcopy() (ou memcpy()) sont theoriquement necessaires, car il est possible que les elements de la structure sockaddr_in ne soient pas forcement alignes sur un word boundary en memoire.. en pratique ce n'est jamais le cas avec les compilos modernes, mais ca ne mange pas de pain..

    attention, tu vas recuperer l'IP externe de ta machine locale (si tu es derriere un routeur qui fait du NAT, ce sera l'IP de ta machine sur le LAN, pas sur Internet).

    voici ce que ca donne chez moi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    % ./getaddr 
    10.13.1.30
    si tu veux recuperer l'IP externe, le mieux est de prevoir un type de message dans ton protocole qui va renvoyer au client son IP telle que vue par le serveur.

    j'espere que ces quelques infos t'ont eclaire.

    -pirus.

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    j'ai besoin de recuperer mon adresse ip public (la meme qu'on obtient en faisant un /sbin/ifconfig ou un ipconfig sous windows par exemple)
    L'adresse publique et l'adresse fournie par ces utilitaires n'a rien à voir. Il suffit de posséder un routeur pour s'en apercevoir, ces utilitaires ne fourniront que l'adresse sur le réseau local.
    Le seul moyen de connaître son adresse publique c'est de la demander à un serveur distant.

  7. #7
    Membre régulier Avatar de psyphi
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    119
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Allemagne

    Informations professionnelles :
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2006
    Messages : 119
    Points : 120
    Points
    120
    Par défaut
    Genre ce petit code que j'avais codé il n'y a pas très longtemps:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    /*
     * get_ip()
     */
    char * get_ip() {
    	fprintf(stdout,"get_ip()\r\n");
     
    	char * strGet = "GET / HTTP/1.0\r\n\r\n";
        char buffer[1024];
        char * ip = (char *)malloc(15 * sizeof(char));
        short iBytesRecv = 0;
     
        struct hostent * host;
        SOCKADDR_IN sin;
        SOCKET socket_local;
        WSADATA wsaData;
     
        int size = sizeof(sin);
     
        int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
        if ( iResult != NO_ERROR )
          printf("Error at WSAStartup()\r\n");
     
        socket_local = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
      	if ( socket_local == INVALID_SOCKET )
      	{
    		printf( "Error at socket(): %ld\r\n", WSAGetLastError() );
    		WSACleanup();
    		return "Error at socket";
        }
     
        if( (host = gethostbyname ("whatismyip.org")) == NULL)
        {
    		printf("Error at gethostbyname(): %ld\n", WSAGetLastError());
    		closesocket(socket_local);
    		WSACleanup();
    		return "Error at gethostbyname\r\n";
        }
     
       	memset(&sin, 0, sizeof(sin));
       	sin.sin_family = AF_INET;
        sin.sin_port = htons(80);
        memcpy(&(sin.sin_addr),host->h_addr,host->h_length);
     
        if( connect(socket_local, (struct sockaddr*)&sin, size) < 0 )
        {
    		printf("Error at connect(): %ld\r\n", WSAGetLastError() );
    		closesocket(socket_local);
    		WSACleanup();
    		return "Error at connect";
        }
        send(socket_local, strGet, strlen(strGet), 0);
        if( (iBytesRecv = recv(socket_local, buffer, 1024, 0)) == -1)
        {
    		printf("Error at send(): %ld\r\n", WSAGetLastError() );
    		closesocket(socket_local);
    		WSACleanup();
    		return "Error at send";
        }
        buffer[iBytesRecv] = '\0';
        sprintf(ip, strstr(buffer, "\r\n\r\n"));
     
        closesocket(socket_local);
        WSACleanup();
     
    	return ip;
    }
    Bon c pour du win32 mais c'est facilment portable si tu connais les sockets de berkeley

Discussions similaires

  1. Connaitre son adresse IP Publique
    Par marouene_ dans le forum Linux
    Réponses: 18
    Dernier message: 23/11/2011, 22h47
  2. Réponses: 5
    Dernier message: 24/05/2008, 07h31
  3. tomcat depuis son adresse ip publique
    Par yodark dans le forum Tomcat et TomEE
    Réponses: 3
    Dernier message: 17/03/2008, 21h31
  4. Connaitre son adresse IP sur internet
    Par dafdan dans le forum C++Builder
    Réponses: 4
    Dernier message: 25/01/2007, 21h12
  5. connaitre son adresse IP
    Par Tex-Twil dans le forum Programmation et administration système
    Réponses: 4
    Dernier message: 14/01/2006, 16h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo