C++ 实现在 Windows 系统获取 ipv4 和 ipv6 地址

c++ c++ 1381 人阅读 | 0 人回复

发表于 2023-5-23 10:44:50 | 显示全部楼层 |阅读模式

程序源码如下:

1. 形参ipv4, ipv6为外部调用者传入,用来保存ipv4地址和ipv6地址,

2. MAX_PATH为自定义宏, 为数值260, IPVN_SIZE为数值50, DEFAULT_STR_PORT为字符串"8080"

  1. #include <winsock2.h>
  2. #include <ws2tcpip.h>
  3. #pragma comment(lib,"Ws2_32.lib")


  4. void CAllBox::getLocalIPv4( char * ip4)
  5. {
  6.         // 获得本机主机名
  7. #ifdef _WIN32
  8.         INT rc;
  9.         WSADATA wsaData;

  10.         rc = WSAStartup(MAKEWORD(2, 2), &wsaData);
  11.         if (rc) {
  12.                 return ;
  13.         }
  14. #endif

  15.         char hostname[MAX_PATH];
  16.         memset(hostname, 0, MAX_PATH);
  17.         gethostname(hostname, MAX_PATH);
  18.         struct hostent FAR* lpHostEnt = gethostbyname(hostname);
  19.         if (lpHostEnt == NULL)
  20.         {
  21.                 return;
  22.         }

  23.         // 取得IP地址列表中的第一个为返回的IP, 即有线网卡IP(因为一台主机可能会绑定多个IP)
  24.         LPSTR lpAddr = lpHostEnt->h_addr_list[0];

  25.         // 将IP地址转化成字符串形式
  26.         struct in_addr inAddr;
  27.         memmove(&inAddr, lpAddr, 4);

  28. #ifdef _WIN32
  29.         WSACleanup();
  30. #endif

  31.         strncpy(ip4, inet_ntoa(inAddr), strlen(inet_ntoa(inAddr)));

  32.         return;
  33. }


  34. void CAllBox::getLocalIPv6(char* ip6)
  35. {
  36. #ifdef _WIN32
  37.         INT rc;
  38.         WSADATA wsaData;

  39.         rc = WSAStartup(MAKEWORD(2, 2), &wsaData);
  40.         if (rc) {
  41.                 return ;
  42.         }
  43. #endif

  44.         PHOSTENT hostinfo;
  45.         char hostname[HOSTNAME_LEN];      //主机名  
  46.         char *port = DEFAULT_STR_PORT;                        //端口号
  47.         int ilRc;

  48.     memset(hostname, 0, HOSTNAME_LEN);

  49.         gethostname(hostname, sizeof(hostname));

  50.         struct addrinfo hint;
  51.         struct addrinfo *ailist = NULL, *aip = NULL;
  52.         struct sockaddr_in6 *sinp6;

  53.         hint.ai_family = AF_INET6;          /*  hint 的限定设置  */
  54.         hint.ai_socktype = SOCK_STREAM;     /*   这里可是设置 socket type    比如  SOCK——DGRAM */
  55.         hint.ai_flags = AI_PASSIVE;         // flags 的标志很多  。常用的有AI_CANONNAME;
  56.         hint.ai_protocol = DEFAULT_PROT;               /*  设置协议  一般为0,默认 */
  57.         hint.ai_addrlen = DEFAULT_ADDRLEN;                /*  下面不可以设置,为0,或者为NULL  */
  58.         hint.ai_canonname = NULL;
  59.         hint.ai_addr = NULL;
  60.         hint.ai_next = NULL;
  61.         ilRc = getaddrinfo(hostname, port, &hint, &ailist);    /*通过主机名获得地址信息*/
  62.         if (ilRc < 0)
  63.         {
  64.                 char str_error[ERR_MSG_LEN];
  65.                 strcpy(str_error, (char *)gai_strerror(errno));
  66.                 return ;
  67.         }
  68.         if (ailist == NULL)
  69.         {
  70.                 return ;
  71.         }

  72.         aip = ailist;
  73.         aip->ai_family == AF_INET6;
  74.         sinp6 = (struct sockaddr_in6 *)aip->ai_addr;     
  75.         inet_ntop(AF_INET6, (void*)&sinp6->sin6_addr, ip6, IPVN_SIZE);

  76. #ifdef _WIN32
  77.         WSACleanup();
  78. #endif

  79.         return ;
  80. }
复制代码


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则