C++获得本机所有网卡的IP和MAC地址信息的实现方法

2025-05-27 0 66

一台机器上可能不只有一个网卡,但每一个网卡只有一个MAC地址,而每一个网卡可能配置有多个IP地址;如平常的笔记本电脑中,就会有无线网卡和有线网卡(网线接口)两种;因此,如果要获得本机所有网卡IP和MAC地址信息,则必须顺序获得每个网卡,再依次获取其信息等;在windows sdk中,用IP_ADAPTER_INFO结构体存储网卡信息,包括网卡名、网卡描述、网卡MAC地址、网卡IP等,该结构体的主要描述如下所示:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29
typedef struct _IP_ADAPTER_INFO {

  struct _IP_ADAPTER_INFO* Next;//指向链表中下一个适配器信息的指针

  DWORD ComboIndex;//预留值

  char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];//使用ANSI字符串表示的适配器名称

  char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];//使用ANSI字符串表示的适配器描述

  UINT AddressLength;//适配器硬件地址以字节计算的长度

  BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];//硬件地址以BYTE数组所表示

  DWORD Index;//适配器索引

UINT Type;//适配器类型,主要有以下几种:

/*

* MIB_IF_TYPE_OTHER 1

* MIB_IF_TYPE_ETHERNET 6

* MIB_IF_TYPE_TOKENRING 9

* MIB_IF_TYPE_FDDI 15

* MIB_IF_TYPE_PPP 23

* MIB_IF_TYPE_LOOPBACK 24

* MIB_IF_TYPE_SLIP 28

*/

  UINT DhcpEnabled;//指定这个适配器是否开启DHCP

  PIP_ADDR_STRING CurrentIpAddress;//预留值

  IP_ADDR_STRING IpAddressList;//该适配器的IPv4地址链表

  IP_ADDR_STRING GatewayList;//该适配器的网关IPv4地址链表

  IP_ADDR_STRING DhcpServer;//该适配器的DHCP服务器的IPv4 地址链表

  BOOL HaveWins;

  IP_ADDR_STRING PrimaryWinsServer;

  IP_ADDR_STRING SecondaryWinsServer;

  time_t LeaseObtained;

  time_t LeaseExpires;

  } IP_ADAPTER_INFO,*PIP_ADAPTER_INFO;

由于可能有多个网卡,因此struct _IP_ADAPTER_INFO* Next字段为一个链表结构指针,由于一个网卡可能有多个IP,因此IP_ADDR_STRING字段应该也是一个链表结构,其信息如下所示:

?

1

2

3

4

5

6

7
typedef struct _IP_ADDR_STRING

{

struct _IP_ADDR_STRING* Next; //指向同类型节点,即下一个IP(如果有多IP的话)

IP_ADDRESS_STRING IpAddress; //IP地址信息

IP_MASK_STRING IpMask; //IP子网掩码

DWORD Context;// 网络表入口。这个值对应着AddIPAddredd和DeleteIPAddress函数中的NTEContext参数

} IP_ADDR_STRING;

综上所述,用下图来描述网卡的结构存储信息,也许更明朗:

C++获得本机所有网卡的IP和MAC地址信息的实现方法

在基本了解以上信息后,就可以调用GetAdaptersInfo函数来获取相关网卡信息了,其通用的代码如下所示:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101
#include <WinSock2.h>

#include <Iphlpapi.h>

#include <iostream>

using namespace std;

#pragma comment(lib,"Iphlpapi.lib") //需要添加Iphlpapi.lib库

int main(int argc, char* argv[])

{

//PIP_ADAPTER_INFO结构体指针存储本机网卡信息

PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO();

//得到结构体大小,用于GetAdaptersInfo参数

unsigned long stSize = sizeof(IP_ADAPTER_INFO);

//调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量;其中stSize参数既是一个输入量也是一个输出量

int nRel = GetAdaptersInfo(pIpAdapterInfo,&stSize);

//记录网卡数量

int netCardNum = 0;

//记录每张网卡上的IP地址数量

int IPnumPerNetCard = 0;

if (ERROR_BUFFER_OVERFLOW == nRel)

{

//如果函数返回的是ERROR_BUFFER_OVERFLOW

//则说明GetAdaptersInfo参数传递的内存空间不够,同时其传出stSize,表示需要的空间大小

//这也是说明为什么stSize既是一个输入量也是一个输出量

//释放原来的内存空间

delete pIpAdapterInfo;

//重新申请内存空间用来存储所有网卡信息

pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[stSize];

//再次调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量

nRel=GetAdaptersInfo(pIpAdapterInfo,&stSize);

}

if (ERROR_SUCCESS == nRel)

{

//输出网卡信息

//可能有多网卡,因此通过循环去判断

while (pIpAdapterInfo)

{

cout<<"网卡数量:"<<++netCardNum<<endl;

cout<<"网卡名称:"<<pIpAdapterInfo->AdapterName<<endl;

cout<<"网卡描述:"<<pIpAdapterInfo->Description<<endl;

switch(pIpAdapterInfo->Type)

{

case MIB_IF_TYPE_OTHER:

cout<<"网卡类型:"<<"OTHER"<<endl;

break;

case MIB_IF_TYPE_ETHERNET:

cout<<"网卡类型:"<<"ETHERNET"<<endl;

break;

case MIB_IF_TYPE_TOKENRING:

cout<<"网卡类型:"<<"TOKENRING"<<endl;

break;

case MIB_IF_TYPE_FDDI:

cout<<"网卡类型:"<<"FDDI"<<endl;

break;

case MIB_IF_TYPE_PPP:

printf("PP\\n");

cout<<"网卡类型:"<<"PPP"<<endl;

break;

case MIB_IF_TYPE_LOOPBACK:

cout<<"网卡类型:"<<"LOOPBACK"<<endl;

break;

case MIB_IF_TYPE_SLIP:

cout<<"网卡类型:"<<"SLIP"<<endl;

break;

default:

break;

}

cout<<"网卡MAC地址:";

for (DWORD i = 0; i < pIpAdapterInfo->AddressLength; i++)

if (i < pIpAdapterInfo->AddressLength-1)

{

printf("%02X-", pIpAdapterInfo->Address[i]);

}

else

{

printf("%02X\\n", pIpAdapterInfo->Address[i]);

}

cout<<"网卡IP地址如下:"<<endl;

//可能网卡有多IP,因此通过循环去判断

IP_ADDR_STRING *pIpAddrString =&(pIpAdapterInfo->IpAddressList);

do

{

cout<<"该网卡上的IP数量:"<<++IPnumPerNetCard<<endl;

cout<<"IP 地址:"<<pIpAddrString->IpAddress.String<<endl;

cout<<"子网地址:"<<pIpAddrString->IpMask.String<<endl;

cout<<"网关地址:"<<pIpAdapterInfo->GatewayList.IpAddress.String<<endl;

pIpAddrString=pIpAddrString->Next;

} while (pIpAddrString);

pIpAdapterInfo = pIpAdapterInfo->Next;

cout<<"--------------------------------------------------------------------"<<endl;

}

}

//释放内存空间

if (pIpAdapterInfo)

{

delete pIpAdapterInfo;

}

return 0;

}

执行结果:

C++获得本机所有网卡的IP和MAC地址信息的实现方法

第二种求IP地址的方法:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33
#include <winsock.h>

#include <stdio.h>

#pragma comment(lib,"ws2_32.lib") //用于链接到ws2_32.lib这个库

void CheckIP(void)//CheckIP函数,用于获取本机IP地址

{

WORD wVersionRequested;//WORD类型变量,用于存放Winsock版本的值

WSADATA wsaData;

char name[255];//用于存放主机名

PHOSTENT hostinfo;

wVersionRequested=MAKEWORD(2,0);

//调用MAKEWORD()函数获得Winsock版本,用于加载Winsock库

if(WSAStartup(wVersionRequested,&wsaData) == 0)

{

//加载Winsock库,如果WSAStartup()函数的返回值为0,说明加载成功

if(gethostname(name,sizeof(name))==0)

{

if((hostinfo = gethostbyname(name) )!= NULL)

{

//如果获得主机名成功的话,调用inet_ntoa()函数取得IP地址

LPCSTR ip = inet_ntoa(*(struct in_addr *)*hostinfo->h_addr_list);

printf("本机的IP地址是:%s\\n",ip);//输出ip地址

printf("本机的名称是:%s\\n",name);

}

}

WSACleanup();

}

}

int main()

{

CheckIP();//调用CheckIP()函数获得并输出IP地址

return 0;

}

以上就是小编为大家带来的C++获得本机所有网卡IP和MAC地址信息的实现方法全部内容了,希望大家多多支持快网idc~

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 C++获得本机所有网卡的IP和MAC地址信息的实现方法 https://www.kuaiidc.com/74532.html

相关文章

发表评论
暂无评论