作者在 2008-06-10 17:03:02 发布以下内容
☆ 如何获取网卡的MAC地址?
进行网络底层编程时,这是一个大家都无法回避的问题,也是一个比较棘手的问题。就我所知道的方法有如下几种:
1 使用NetBois命令。
在网上搜索,可以发现这是最常见的方法。不过有点复杂,使用起来也有限制,如果机器禁用了NetBois,那么这种方法就行不通了。
在网上搜索,可以发现这是最常见的方法。不过有点复杂,使用起来也有限制,如果机器禁用了NetBois,那么这种方法就行不通了。
2 使用Winpcap Packet.dll中的PacketGetNetType函数。
熟悉Winpcap的人都知道,Winpcap常规及推荐使用的是wpcap.dll,winpcap并没有提供对Packet.dll的API支持,在开发文档中没有关于Packet.dll的文档。因此使用这种方法不规范也比较麻烦(需要安装winpcap驱动)。
熟悉Winpcap的人都知道,Winpcap常规及推荐使用的是wpcap.dll,winpcap并没有提供对Packet.dll的API支持,在开发文档中没有关于Packet.dll的文档。因此使用这种方法不规范也比较麻烦(需要安装winpcap驱动)。
3 使用ipconfig /all命令获取,并写入管道,我们的程序再从管道种读取 "Physical Address. . . . . . . . . :"
这是我在CSDN上看到的一种方法。很巧妙,不过也比较麻烦,特别是有多个网卡时就更不实用了。
这是我在CSDN上看到的一种方法。很巧妙,不过也比较麻烦,特别是有多个网卡时就更不实用了。
4 使用GetAdaptersAddresses/GetAdaptersInfo函数。
最简单的方法。但是在MSDN6.0中查询不到该函数。该函数是在Windows 2000以上的系统中才有的函数,VC++6.0默认所带的SDK是win98的,所以要使用这个函数,就需要安装相应的SDK,我的系统是"XP",因此就要安装“XPSP2 PSDK”。系统相关的SDK可以到微软官方下载。下面是XPSP2 PSDK的下载地址。
(http://www.microsoft.com:80/msdownload/platformsdk/sdkupdate/XPSP2FULLInstall.htm)
最简单的方法。但是在MSDN6.0中查询不到该函数。该函数是在Windows 2000以上的系统中才有的函数,VC++6.0默认所带的SDK是win98的,所以要使用这个函数,就需要安装相应的SDK,我的系统是"XP",因此就要安装“XPSP2 PSDK”。系统相关的SDK可以到微软官方下载。下面是XPSP2 PSDK的下载地址。
(http://www.microsoft.com:80/msdownload/platformsdk/sdkupdate/XPSP2FULLInstall.htm)
☆ 什么是SDK?
微软每推出一个重要的windows版本,一般都会同时推出一个SDK(Software Development Kit)。SDK包含了开发该windows版本所需的windows函数和常数定义、API函数说明文档、相关工具和示例。SDK一般使用C语言,但不包括编译器。高版本VC++包括了SDK所有的头文件、帮助、示例和工具,不需要再安装SDK,低版本如VC++5.0则需要安装SDK。从windows 98开始,windows SDK叫Platform SDK(http://www.microsoft.com/downloads/details.aspx?FamilyId=A55B6B43-E24F-4EA3-A93E-40C0EC4F68E5&displaylang=en),包含最新的windows API函数的有关声明、例子。
☆如何安装实用新版的SDK?
我安装的是“XPSP2 PSDK”。先到微软官方下载相关的安装文件。下载完毕你会发现并没有setup.exe或者install.exe之类
的安装主程序文件。查看下载页上的安装说明,原来需要先用PSDK-FULL.bat(下载页面上有该文件)对.cab文件进行解压缩。
命令格式是:“psdk-full 解压缩后的路径”,需要至少 1.4 GB 的空闲硬盘空间。解压缩可能需要好几分钟(我大概用了1分
钟吧)。
解压缩完后,在解压出来的文件中就能找到“Setup.Exe”文件了。和安装普通程序一样安装就ok了。
SDK安装完成后,还需要在VC++6.0中做相应的设置,然它能引用到SDK中的文件。
(1)安装完毕后,打开VC++ 6.0,点Tools->Options->Directories选项卡,在Executable Files下,添加BIN文件
解压缩完后,在解压出来的文件中就能找到“Setup.Exe”文件了。和安装普通程序一样安装就ok了。
SDK安装完成后,还需要在VC++6.0中做相应的设置,然它能引用到SDK中的文件。
(1)安装完毕后,打开VC++ 6.0,点Tools->Options->Directories选项卡,在Executable Files下,添加BIN文件
(2)在Include Files添加Include文件:
(3)在Library Files添加Lib文件:
注意:添加成功以后,一定要用那个向上的箭头 把我们新添加的路径放在最上面,因为程序在编译过程中搜索路径的时候有优先搜索的功能。
注意:添加成功以后,一定要用那个向上的箭头 把我们新添加的路径放在最上面,因为程序在编译过程中搜索路径的时候有优先搜索的功能。
☆使用GetAdaptersAddresses获取MAC地址(不能获取IP,NetMask,NetGate等信息)
#include<winsock2.h>
#include<Iphlpapi.h>
#include<stdio.h>
#pragma comment(lib,"Iphlpapi.lib")
int main()
{
PIP_ADAPTER_ADDRESSES pAddresses;
ULONG outBufLen = 0;
DWORD dwRetVal = 0;
pAddresses = (IP_ADAPTER_ADDRESSES*) malloc(sizeof(IP_ADAPTER_ADDRESSES));
// 第一次使用 GetAdaptersAddresses 从 outBufLen 中获取需要的缓冲区大小
if (GetAdaptersAddresses(AF_INET,
0,
NULL,
pAddresses,
&outBufLen) == ERROR_BUFFER_OVERFLOW)
{
GlobalFree(pAddresses);
pAddresses = (IP_ADAPTER_ADDRESSES*) malloc(outBufLen);
}
// 第二次调用GetAdaptersAddresses 获取实际想获取的信息.
if ((dwRetVal = GetAdaptersAddresses(AF_INET,
0,
NULL,
pAddresses,
&outBufLen)) == NO_ERROR)
{
while (pAddresses)
{
printf("AdapterName: %S\n",pAddresses->AdapterName);
printf("Description: %S\n", pAddresses->Description);
printf("PhysicalAddress: %02x-%02x-%02x-%02x-%02x-%02x\n\n",
pAddresses->PhysicalAddress[0],
pAddresses->PhysicalAddress[1],
pAddresses->PhysicalAddress[2],
pAddresses->PhysicalAddress[3],
pAddresses->PhysicalAddress[4],
pAddresses->PhysicalAddress[5]);
#include<Iphlpapi.h>
#include<stdio.h>
#pragma comment(lib,"Iphlpapi.lib")
int main()
{
PIP_ADAPTER_ADDRESSES pAddresses;
ULONG outBufLen = 0;
DWORD dwRetVal = 0;
pAddresses = (IP_ADAPTER_ADDRESSES*) malloc(sizeof(IP_ADAPTER_ADDRESSES));
// 第一次使用 GetAdaptersAddresses 从 outBufLen 中获取需要的缓冲区大小
if (GetAdaptersAddresses(AF_INET,
0,
NULL,
pAddresses,
&outBufLen) == ERROR_BUFFER_OVERFLOW)
{
GlobalFree(pAddresses);
pAddresses = (IP_ADAPTER_ADDRESSES*) malloc(outBufLen);
}
// 第二次调用GetAdaptersAddresses 获取实际想获取的信息.
if ((dwRetVal = GetAdaptersAddresses(AF_INET,
0,
NULL,
pAddresses,
&outBufLen)) == NO_ERROR)
{
while (pAddresses)
{
printf("AdapterName: %S\n",pAddresses->AdapterName);
printf("Description: %S\n", pAddresses->Description);
printf("PhysicalAddress: %02x-%02x-%02x-%02x-%02x-%02x\n\n",
pAddresses->PhysicalAddress[0],
pAddresses->PhysicalAddress[1],
pAddresses->PhysicalAddress[2],
pAddresses->PhysicalAddress[3],
pAddresses->PhysicalAddress[4],
pAddresses->PhysicalAddress[5]);
pAddresses = pAddresses->Next;
}
}
else
printf("Get Adapter Information failed!\n");
}
}
else
printf("Get Adapter Information failed!\n");
return 0;
}
}
推荐!
☆使用GetAdaptersInfo获取网卡详细信息(包括:Adapter Name,Mac,Ip,NetMask,NetGate)
#include<winsock2.h>
#include<Iphlpapi.h>
#include<stdio.h>
#pragma comment(lib,"Iphlpapi.lib")
int main()
{
PIP_ADAPTER_INFO pAdapterInfo;
PIP_ADAPTER_INFO pAdapter = NULL;
DWORD dwRetVal = 0;
ULONG ulOutBufLen;
#include<Iphlpapi.h>
#include<stdio.h>
#pragma comment(lib,"Iphlpapi.lib")
int main()
{
PIP_ADAPTER_INFO pAdapterInfo;
PIP_ADAPTER_INFO pAdapter = NULL;
DWORD dwRetVal = 0;
ULONG ulOutBufLen;
pAdapterInfo=(PIP_ADAPTER_INFO)malloc(sizeof(IP_ADAPTER_INFO));
ulOutBufLen = sizeof(IP_ADAPTER_INFO);
// 第一次调用GetAdapterInfo获取ulOutBufLen大小
if (GetAdaptersInfo( pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW)
{
free(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO *) malloc (ulOutBufLen);
}
if ((dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
pAdapter = pAdapterInfo;
while (pAdapter)
{
printf("Adapter Name: \t%s\n", pAdapter->AdapterName);
printf("Adapter Desc: \t%s\n", pAdapter->Description);
printf("MAC Addr: \t%02x-%02x-%02x-%02x-%02x-%02x\n",
pAdapter->Address[0],
pAdapter->Address[1],
pAdapter->Address[2],
pAdapter->Address[3],
pAdapter->Address[4],
pAdapter->Address[5]);
printf("IP Address: \t%s\n", pAdapter->IpAddressList.IpAddress.String);
printf("IP Mask: \t%s\n", pAdapter->IpAddressList.IpMask.String);
printf("Gateway: \t%s\n", pAdapter->GatewayList.IpAddress.String);
pAdapter = pAdapter->Next;
}
}
else
{
printf("Call to GetAdaptersInfo failed.\n");
}
}
ulOutBufLen = sizeof(IP_ADAPTER_INFO);
// 第一次调用GetAdapterInfo获取ulOutBufLen大小
if (GetAdaptersInfo( pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW)
{
free(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO *) malloc (ulOutBufLen);
}
if ((dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
pAdapter = pAdapterInfo;
while (pAdapter)
{
printf("Adapter Name: \t%s\n", pAdapter->AdapterName);
printf("Adapter Desc: \t%s\n", pAdapter->Description);
printf("MAC Addr: \t%02x-%02x-%02x-%02x-%02x-%02x\n",
pAdapter->Address[0],
pAdapter->Address[1],
pAdapter->Address[2],
pAdapter->Address[3],
pAdapter->Address[4],
pAdapter->Address[5]);
printf("IP Address: \t%s\n", pAdapter->IpAddressList.IpAddress.String);
printf("IP Mask: \t%s\n", pAdapter->IpAddressList.IpMask.String);
printf("Gateway: \t%s\n", pAdapter->GatewayList.IpAddress.String);
pAdapter = pAdapter->Next;
}
}
else
{
printf("Call to GetAdaptersInfo failed.\n");
}
}
本博客于即日起(2009.2.26)停止更新,