• windows 获取本机(全部)IPv4、IPv6、MAC地址方法 (C/C++)


    windows下获取IP地址的两种方法;

    一种可以获取IPv4和IPv6,但是需要WSAStartup;

    一种只能取到IPv4,但是不需要WSAStartup;

    如下:

    方法一:(可以获取IPv4和IPv6)

     1 #define _WINSOCK_DEPRECATED_NO_WARNINGS
     2 #include <Winsock2.h>
     3 #include <stdio.h>
     4 #include <iostream>
     5 #include <cstring>
     6 #include<ws2tcpip.h>
     7 #pragma comment(lib, "ws2_32.lib ")  //linking to the library
     8 using namespace std;
     9 int get_ip()
    10 {
    11     struct addrinfo *ailist, *aip;
    12     struct addrinfo hint;
    13     struct sockaddr_in6 *sinp6;
    14     PHOSTENT hostinfo;
    15     char hostname[255] = {0}; //主机名   
    16     char *port = "3294";      //端口号 
    17     const char *addr;
    18     int ilRc;
    19     gethostname(hostname, sizeof(hostname));
    20     if((hostinfo = gethostbyname(hostname)) == NULL) //获得本地ipv4地址
    21     {
    22         errno = GetLastError();
    23         fprintf(stderr,"gethostbyname Error:%d
    ", errno);
    24         return 1;
    25     }
    26     LPCSTR ip;
    27     while(*(hostinfo->h_addr_list) != NULL) //输出ipv4地址
    28     {
    29         ip = inet_ntoa(*(struct in_addr *) *hostinfo->h_addr_list);
    30         printf("ipv4 addr = %s
    
    ", ip);
    31         hostinfo->h_addr_list++;
    32     }
    33     hint.ai_family = AF_INET6;        //hint 的限定设置
    34     hint.ai_socktype = SOCK_STREAM;   //这里可是设置 socket type    比如  SOCK_DGRAM
    35     hint.ai_flags = AI_PASSIVE;       // flags 的标志很多。常用的有AI_CANONNAME;
    36     hint.ai_protocol = 0;             //设置协议  一般为0,默认
    37     hint.ai_addrlen = 0;              //下面不可以设置,为0,或者为NULL
    38     hint.ai_canonname = NULL;
    39     hint.ai_addr = NULL;
    40     hint.ai_next = NULL;
    41     ilRc = getaddrinfo(hostname, port, &hint, &ailist); //通过主机名获得地址信息
    42     if (ilRc < 0)
    43     {
    44         char str_error[100];
    45         strcpy(str_error, (char *)gai_strerror(errno));
    46         printf("str_error = %s", str_error);
    47         return 0;
    48     }
    49     if(ailist == NULL)
    50     {
    51         printf("sorry not find the IP address,please try again 
    ");
    52     }
    53     for (aip = ailist; aip != NULL; aip = aip->ai_next) //显示获取的信息
    54     {
    55         aip->ai_family == AF_INET6;
    56         sinp6 = (struct sockaddr_in6 *)aip->ai_addr;    //为什么是for 循环 ,先向下看
    57         int i;
    58         printf("ipv6 addr = ");
    59         for(i = 0; i < 16; i++)
    60         {
    61             if(((i-1)%2) && (i>0))
    62             {
    63                 printf(":");
    64             }
    65             printf("%02x",sinp6->sin6_addr.u.Byte[i]);
    66         }
    67         printf(" 
    ");
    68         printf(" 
    ");
    69     }
    70     while(1);
    71 }
    72 int main(){
    73 
    74     WORD wVersionRequested;
    75     WSADATA wsaData;
    76     int err;
    77     wVersionRequested = MAKEWORD( 1, 1 );
    78     err = WSAStartup( wVersionRequested, &wsaData );//initiate the ws2_32.dll and match the version
    79     if ( err != 0 )
    80     {
    81         return 0;
    82     }
    83     if ( LOBYTE( wsaData.wVersion ) != 1 ||   //if the version is not matched ,then quit and terminate the ws3_32.dll 
    84         HIBYTE( wsaData.wVersion ) != 1 )
    85     {
    86         WSACleanup( );
    87         return 0;
    88     }
    89     get_ip();
    90     WSACleanup( );
    91     return 0;
    92 }

    方法二:(只能取到IPv4)

     1 //#define _WINSOCK_DEPRECATED_NO_WARNINGS
     2 #include <WinSock2.h>
     3 #include <Iphlpapi.h>
     4 #include <iostream>
     5 using namespace std;
     6 #pragma comment(lib,"Iphlpapi.lib") //需要添加Iphlpapi.lib库
     7 //#pragma comment(lib, "ws2_32.lib")
     8 
     9 int main(int argc, char* argv[])
    10 {
    11     //PIP_ADAPTER_INFO结构体指针存储本机网卡信息
    12     PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO();
    13     //得到结构体大小,用于GetAdaptersInfo参数
    14     unsigned long stSize = sizeof(IP_ADAPTER_INFO);
    15     //调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量;其中stSize参数既是一个输入量也是一个输出量
    16     int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);
    17     //记录网卡数量
    18     DWORD netCardNum = 0;
    19     GetNumberOfInterfaces(&netCardNum);
    20     cout << "网卡数量:" << netCardNum<< endl; netCardNum = 0;
    21     //记录每张网卡上的IP地址数量
    22     int IPnumPerNetCard = 0;
    23     if (ERROR_BUFFER_OVERFLOW == nRel)
    24     {
    25         //如果函数返回的是ERROR_BUFFER_OVERFLOW
    26         //则说明GetAdaptersInfo参数传递的内存空间不够,同时其传出stSize,表示需要的空间大小
    27         //这也是说明为什么stSize既是一个输入量也是一个输出量
    28         //释放原来的内存空间
    29         delete pIpAdapterInfo;
    30         //重新申请内存空间用来存储所有网卡信息
    31         pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[stSize];
    32         //再次调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量
    33         nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);
    34     }
    35     if (ERROR_SUCCESS == nRel)
    36     {
    37         //输出网卡信息
    38         //可能有多网卡,因此通过循环去判断
    39         while (pIpAdapterInfo)
    40         {
    41             cout << "网卡序号:" << ++netCardNum <<"	"<<pIpAdapterInfo->Index << endl;
    42             cout << "网卡名称:" << pIpAdapterInfo->AdapterName << endl;
    43             cout << "网卡描述:" << pIpAdapterInfo->Description << endl;
    44             cout << "网卡类型:";
    45             switch (pIpAdapterInfo->Type)
    46             {
    47             case MIB_IF_TYPE_OTHER:        cout << "OTHER" << endl; break;
    48             case MIB_IF_TYPE_ETHERNET:    cout << "ETHERNET" << endl; break;
    49             case MIB_IF_TYPE_TOKENRING:    cout << "TOKENRING" << endl; break;
    50             case MIB_IF_TYPE_FDDI:        cout << "FDDI" << endl; break;
    51             case MIB_IF_TYPE_PPP:        cout << "PPP" << endl; break;
    52             case MIB_IF_TYPE_LOOPBACK:    cout << "LOOPBACK" << endl; break;
    53             case MIB_IF_TYPE_SLIP:        cout << "SLIP" << endl; break;
    54             default:                    cout << "" << endl; break;
    55             }
    56             cout << "网卡MAC地址:";
    57             for (DWORD i = 0; i < pIpAdapterInfo->AddressLength; i++)
    58                 if (i < pIpAdapterInfo->AddressLength - 1)
    59                 {
    60                     printf("%02X-", pIpAdapterInfo->Address[i]);
    61                 }
    62                 else
    63                 {
    64                     printf("%02X
    ", pIpAdapterInfo->Address[i]);
    65                 }
    66             cout << "网卡IP地址如下:" << endl;
    67             IPnumPerNetCard = 0;
    68             //可能网卡有多IP,因此通过循环去判断
    69             IP_ADDR_STRING *pIpAddrString = &(pIpAdapterInfo->IpAddressList);
    70             do
    71             {
    72                 cout << "该网卡上的IP数量:" << ++IPnumPerNetCard << endl;
    73                 cout << "IP 地址:" << pIpAddrString->IpAddress.String << endl;
    74                 cout << "子网掩码:" << pIpAddrString->IpMask.String << endl;
    75                 cout << "网关地址:" << pIpAdapterInfo->GatewayList.IpAddress.String << endl;
    76                 pIpAddrString = pIpAddrString->Next;
    77             } while (pIpAddrString);
    78             pIpAdapterInfo = pIpAdapterInfo->Next;
    79             cout << "--------------------------------------------------------------------" << endl;
    80         }
    81 
    82     }
    83     //释放内存空间
    84     if (pIpAdapterInfo)
    85     {
    86         delete pIpAdapterInfo;
    87     }
    88     return 0;
    89 }

    Linux下,详见:http://www.cnblogs.com/lzpong/p/6956439.html

  • 相关阅读:
    计算机网络 chapter 6 应用层
    计算机网络 chapter 4 网络层
    计算机网络 chapter 2 物理层
    计算机网络 chapter3数据链路层
    计算机网络 chapter 1 概述
    文章
    进程池线程池 协程
    MySQL
    同步锁 死锁与递归锁 信号量 线程queue event事件
    GIL全局解释器
  • 原文地址:https://www.cnblogs.com/lzpong/p/6137652.html
Copyright © 2020-2023  润新知