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\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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM