1. 程式人生 > >用getaddrinfo()函式,通過主機名獲得ipv6和ipv4的地址

用getaddrinfo()函式,通過主機名獲得ipv6和ipv4的地址

111111111111111

using the function "getaddrinfo()" to get the IP address from the hostname you provided;

actually , the "getadrinfo()" function can get not only the IP address,but also more information about hostname,it's pretty useful,
especially for socket programing;

Below is my program to parsing the IP address you wanted;and it's for both ipv4 and ipv6;


#include <Winsock2.h>
#include <stdio.h>
#include <iostream>
#include <cstring>
#include<ws2tcpip.h>

#pragma     comment(lib, "ws2_32.lib ")  //linking to the library

using namespace std;

int main(){

 WORD wVersionRequested;
 WSADATA wsaData;
 int err;


 cout<<"this is the UDP server"<<endl;

//******************//

the flowing text is to match the version of the library and to initialize the library, it's necessary for socket programing;

//*********************//

 wVersionRequested = MAKEWORD( 1, 1 );

 err = WSAStartup( wVersionRequested, &wsaData );//initiate the ws2_32.dll and match the version
 if ( err != 0 ) {
  return 0;
 }

 if ( LOBYTE( wsaData.wVersion ) != 1 ||   //if the version is not matched ,then quit and terminate the ws3_32.dll
  HIBYTE( wsaData.wVersion ) != 1 ) {
   WSACleanup( );
   return 0;
 }

 //************************************************************************************************//
 //copy
 //************************************************************************************************//

 while(1)
 {
  struct addrinfo *ailist, *aip;       

  struct addrinfo hint;       

  struct sockaddr_in6 *sinp6; 
  struct sockaddr_in *sinp4;

  char hostname[255] = {0};      /*  這是使用者名稱 */

  char buf[INET_ADDRSTRLEN];       

  char *server = "3294";                              /*  這是服務埠號 */

  const char *addr;       

  int ilRc;

  cin>>hostname;

  hint.ai_family = AF_UNSPEC;                   /*  hint 的限定設定  */

  hint.ai_socktype = SOCK_STREAM;     /*   這裡可是設定 socket type    比如  SOCK——DGRAM */
  
  hint.ai_flags = AI_PASSIVE;                    /* flags 的標誌很多  。常用的有AI_CANONNAME;   */

  hint.ai_protocol = 0;                               /*  設定協議  一般為0,預設 */          

  hint.ai_addrlen = 0;                                /*  下面不可以設定,為0,或者為NULL  */

  hint.ai_canonname = NULL;       

  hint.ai_addr = NULL;       

  hint.ai_next = NULL;

  ilRc = getaddrinfo(hostname, server, &hint, &ailist);    /*通過主機名獲得地址資訊*/     

  
  if (ilRc < 0)       

  {              
   char str_error[100];               

   strcpy(str_error,gai_strerror(errno));               

   printf("str_error = %s", str_error);               

   return 0;       

  }
  

  if(ailist == NULL)
  {
   printf("sorry not find the IP address,please try again \n");
  }
  for (aip = ailist; aip != NULL; aip = aip->ai_next)                         /* 顯示獲取的資訊  */

  {               
   if(aip->ai_family == AF_INET)
   {
    sinp4 = (struct sockaddr_in *)aip->ai_addr; 
    addr = inet_ntoa( sinp4->sin_addr); 
    printf("ipv4 addr = %s\n", addr?addr:"unknow ");
   }
   else if(aip->ai_family == AF_INET6)
   {
    sinp6 = (struct sockaddr_in6 *)aip->ai_addr;                                  /* 為什麼是for 迴圈 

,先向下看 */
    int i;
    printf("ipv6 addr = ");
    for(i = 0; i < 16; i++)
    {
     if(((i-1)%2) && (i>0))
     {
      printf(":");
     }
     printf("%02x",sinp6->sin6_addr.u.Byte[i]);     
    }
    printf(" \n");
   }  
   printf(" \n"); 

  }
 }

// getaddrinfo();
  while(1);
 
 return 0;
}