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

时间:2024-03-09 17:08:27

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\n", 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\n\n", 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 \n");
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(" \n");
68         printf(" \n");
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 <<"\t"<<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\n", 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