|
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);
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);
61 }
62 else
63 {
64 printf("%02X\n", pIpAdapterInfo->Address);
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 |
|
|