MFC-GetAdaptersAddresses获取网卡信息

MFC-GetAdaptersAddresses获取网卡信息_第1张图片

需要:#pragma comment(lib, "IPHLPAPI.lib")

GetAdaptersAddresses函数参数说明

	ULONG bufferSize = 0;
	ULONG  result = ::GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, nullptr, &bufferSize);
	/*
	参数1:ULONG Family 网络协议族,此参数须为下列值之一
			AF_UNSPEC=0       返回与启用了 IPv4 或 IPv6 的适配器关联的 IPv4 和 IPv6 地址
			AF_INET=2         仅返回与启用了 IPv4 的适配器关联的 IPv4 地址
			AF_INET6=23       仅返回与启用了 IPv6 的适配器关联的 IPv6 地址

	参数2:ULONG Flags  要检索的地址类型
			概念解释:
			单播(Unicast):单播地址是一对一的通信方式,它用于将数据包从源地址发送到目标地址。
					源地址指定发送者的唯一标识符,而目标地址指定接收者的唯一标识符。
					只有目标地址与接收者匹配时,数据包才会传送给接收者。
			广播(Broadcast):广播地址是一对多的通信方式,它用于将数据包发送给同一个网络中的所有设备。
					广播地址是一个特殊的地址,用于指示所有设备都应该接收该数据包。
					广播可以是有限的(局域网内)或无限的(所有网络都接收)。
			多播(Multicast):多播地址是一对多的通信方式,它用于将数据包发送给一组特定的设备,这组设备被称为多播组。
					多播地址也是一种特殊的地址,它表明数据包是按照多播方式进行传输的。只有加入该多播组的设备才会接收到数据包

			此参数是以下值的组合。 如果此参数为零,则将返回单播、任意广播和多播 IP 地址
					GAA_FLAG_SKIP_UNICAST=0x0001     不要返回单播地址
					GAA_FLAG_SKIP_ANYCAST=0x0002     不要返回 IPv6 任何广播地址
					GAA_FLAG_SKIP_MULTICAST=0x0004   不要返回多播地址
					GAA_FLAG_SKIP_DNS_SERVER=0x0008   不要返回 DNS 服务器的地址
					GAA_FLAG_INCLUDE_PREFIX=0x0010    返回此适配器上的 IP 地址前缀列表。 设置此标志后,将返回 IPv6 和 IPv4 地址的 IP 地址前缀。
					GAA_FLAG_SKIP_FRIENDLY_NAME=0x0020    不要返回适配器友好名称
					GAA_FLAG_INCLUDE_WINS_INFO=0x0040     返回Windows Internet名称服务的地址 (WINS) 服务器。
															Windows Vista 及更高版本支持此标志
					GAA_FLAG_INCLUDE_GATEWAYS=0x0080       返回默认网关的地址,Windows Vista 及更高版本支持此标志
					GAA_FLAG_INCLUDE_ALL_INTERFACES=0x0100   返回所有NDIS接口的地址
					GAA_FLAG_INCLUDE_ALL_COMPARTMENTS=0x0200   返回所有路由隔离舱中的地址。此标志当前不受支持,并保留供将来使用
					GAA_FLAG_INCLUDE_TUNNEL_BINDINGORDER=0x0400   返回按隧道绑定顺序排序的适配器地址

	参数3:PVOID Reserved  此参数当前未使用,但保留供将来系统使用。 调用应用程序应为此参数传递 NULL

	参数4:[in, out] PIP_ADAPTER_ADDRESSES AdapterAddresses  指向缓冲区的指针,该缓冲区包含成功返回时 IP_ADAPTER_ADDRESSES 结构的链接列表

	参数5:[in, out] PULONG SizePointer  指向变量的指针,该变量指定 AdapterAddresses 指向的缓冲区的大小

	返回值:如果函数成功,则返回值 ERROR_SUCCESS=0 (定义为 与 NO_ERROR)
			如果函数失败,则返回值为以下错误代码之一
					ERROR_ADDRESS_NOT_ASSOCIATED=1228   地址尚未与网络终结点关联。 DHCP 租约信息可用
					ERROR_BUFFER_OVERFLOW=111          SizePointer 参数指示的缓冲区大小太小,无法保存适配器信息或 AdapterAddresses 参数为 NULL
					ERROR_INVALID_PARAMETER=87   其中一个参数无效。
							对于以下任一情况,将返回此错误: SizePointer 参数为 NULL、 Address 参数不 AF_INET、 AF_INET6或 AF_UNSPEC,
							或者请求的参数的地址信息大于 ULONG_MAX。
					ERROR_NOT_ENOUGH_MEMORY=8     内存资源不足,无法完成操作
					ERROR_NO_DATA=232              找不到所请求参数的地址

	*/

	

GAA_FLAG_INCLUDE_PREFIX 什么是前缀列表 ?

IP 适配器的前缀是指网络接口的 IP 地址所属的网段。例如,对于一个 IPv4 地址 192.168.1.100 和子网掩码 255.255.255.0,它的前缀就是 192.168.1.0/24。同一个网段内的所有网络设备可以通过 IP 地址进行互相通信,而不需要经过路由器

IP_ADAPTER_ADDRESSES 结构体中常用字段的说明:

Next: 指向下一个 IP_ADAPTER_ADDRESSES 结构体的指针。用于遍历多个网络适配器的链表。

AdapterName: 网络适配器的名称,以字符串形式表示。

Description: 网络适配器的描述信息,以字符串形式表示。

FirstUnicastAddress: 指向一个 IP_ADAPTER_UNICAST_ADDRESS 结构体的指针,表示网卡的第一个单播地址(IPv4 或 IPv6)。

FirstAnycastAddress: 指向一个 IP_ADAPTER_ANYCAST_ADDRESS 结构体的指针,表示网卡的第一个任播地址(IPv6)。

FirstMulticastAddress: 指向一个 IP_ADAPTER_MULTICAST_ADDRESS 结构体的指针,表示网卡的第一个组播地址(IPv4 或 IPv6)。

FirstDnsServerAddress: 指向一个 IP_ADAPTER_DNS_SERVER_ADDRESS 结构体的指针,表示网卡的第一个 DNS 服务器地址。

DnsSuffix: DNS 后缀,以字符串形式表示。

PWCHAR FriendlyName: 网络适配器的友好名称,以字符串形式表示。

BYTE PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH] : 网卡的物理地址(MAC 地址),以字节数组形式表示。

ULONG PhysicalAddressLength: 物理地址的长度,以字节数表示

IfIndex: 网络适配器的索引号。

OperStatus: 网络适配器的操作状态,如 UP、DOWN 等。

IfType: 网络适配器的类型,比如以太网、无线网卡等。

Ipv6IfIndex: IPv6 协议的接口索引号。

这些字段提供了有关网络适配器的各种信息,如名称、描述、地址等。通过遍历 IP_ADAPTER_ADDRESSES 的链表,可以获取系统中所有的网络适配器的详细信息

说明:

PhysicalAddressLength

PhysicalAddressLength 是指网卡的物理地址长度(或称为MAC地址长度)。在网络通信中,每个网卡都有一个唯一的物理地址,也称为MAC地址(Media Access Control Address)。

物理地址是由48位(6个字节)的十六进制数字表示的,通常采用冒号或连字符来分隔每个字节。例如,物理地址的格式可以是 00:1A:2B:3C:4D:5E00-1A-2B-3C-4D-5E

PhysicalAddressLength 变量表示物理地址的长度。在通常情况下,物理地址长度是固定的,为6个字节。因此,PhysicalAddressLength 的值通常是6。但是根据特定的网络设备或技术,也可能存在其他长度的物理地址。

通过获取网卡的物理地址长度,我们可以在程序中为物理地址分配足够的内存空间,并确保正确解析和处理物理地址

获取网卡的物理地址(MAC 地址)

	CString str;
	char buff[100];
	DWORD bufflen = 100;
	ULONG outBufLen = 0;
	ULONG dwRetVal = 0;
	PIP_ADAPTER_ADDRESSES pAddresses = nullptr;
	dwRetVal = ::GetAdaptersAddresses(AF_UNSPEC, 0, NULL, nullptr, &outBufLen);
	/*
	第一次GetAdaptersAddresses,outBufLen=0,只是为了获取实际需要的大小
	*/
	//pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
	//根据实际空间大小申请空间

	pAddresses = static_cast(malloc(outBufLen)); // 分配足够的缓冲区空间


	dwRetVal = ::GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST, NULL, pAddresses, &outBufLen);
	/*
	AF_INET  仅返回与启用了 IPv4 的适配器关联的 IPv4 地址
	GAA_FLAG_SKIP_ANYCAST   不要返回 IPv6 任何广播地址

	*/

	if (dwRetVal == NO_ERROR) {

		str.Format(_T("网络适配器的友好名称:%s \n"), pAddresses->FriendlyName);
		//   【以太网】

		str.Format(_T("物理地址的长度:%d \n"), pAddresses->PhysicalAddressLength);
		//  【6】

		int n = sizeof(pAddresses->PhysicalAddress) / sizeof(pAddresses->PhysicalAddress[0]);  //网卡总数
		str.Format(_T("网卡总数:%d \n"), n);
		//  【8】

		for (int i = 0; i < n; i++) {
			str.Format(_T("网卡的物理地址(MAC 地址):n=%d    %x \n"), i, pAddresses->PhysicalAddress[i]);
			::OutputDebugString(str);

			/*
			网卡的物理地址(MAC 地址):n=0    74
			网卡的物理地址(MAC 地址):n=1    d0
			网卡的物理地址(MAC 地址):n=2    2b
			网卡的物理地址(MAC 地址):n=3    b7
			网卡的物理地址(MAC 地址):n=4    3e
			网卡的物理地址(MAC 地址):n=5    44
			网卡的物理地址(MAC 地址):n=6    0
			网卡的物理地址(MAC 地址):n=7    0
			*/

		}
		
	}

你可能感兴趣的:(mfc,c++)