取得系统中网卡MAC地址的三种方法

小傻瓜猫猫

小傻瓜猫猫

2016-02-19 21:31

下面图老师小编跟大家分享取得系统中网卡MAC地址的三种方法,一起来学习下过程究竟如何进行吧!喜欢就赶紧收藏起来哦~
做好的程序员一如做人。多看多想或许他山之石可以攻玉,但永远不要成为代码的奴隶。 CKER
  原著:Borland
  Translated by CKER
  
  第一种方法使用Microsoft的Netbios API。 这是一套通过Winsock提供底层网络支持的命令。使用Netbios的最大缺点是您必须在系统中安装了Netbios服务(假如您在windows网络中启用了文件共享的话,这就不是问题了)。除此此外,这种方法又快又准确。
  
  Netbios API只包括了一个函数,就叫做Netbios。这个函数使用网络控制块(network control block)结构作为参数,这个结构告诉函数要做什么。结构的定义如下:
    typedef strUCt _NCB {
      UCHAR  ncb_command;
      UCHAR  ncb_retcode;
      UCHAR  ncb_lsn;
      UCHAR  ncb_num;
      PUCHAR ncb_buffer;
      Word   ncb_length;
      UCHAR  ncb_callname[NCBNAMSZ];
      UCHAR  ncb_name[NCBNAMSZ];
      UCHAR  ncb_rto;
      UCHAR  ncb_sto;
      void (CALLBACK *ncb_post) (struct _NCB *);
      UCHAR  ncb_lana_num;
      UCHAR  ncb_cmd_cplt;
  #ifdef _WIN64
      UCHAR  ncb_reserve[18];
  #else
      UCHAR  ncb_reserve[10];
  #endif
      HANDLE ncb_event;
  } NCB, *PNCB;
  
  
  
  重点在于ncb_command 成员。这个成员告诉Netbios该作什么。我们使用三个命令来探测MAC地址。他们在MSDN的定义如下:
  命令描述:
  NCBENUM Windows NT/2000: 列举系统中网卡的数量。使用此命令后,ncb_buffer成员指向由LANA_ENUM结构填充的缓冲区。
  NCBENUM 不是标准的 NetBIOS 3.0 命令。
  
  NCBRESET 重置网卡。网卡在接受新的NCB命令之前必须重置。
  NCBASTAT 接受本地或远程接口卡的状态。使用此命令后,ncb_buffer成员指向由ADAPTER_STATUS结构填充的缓冲区,随后是NAME_BUFFER结构的数组。
  
  下面就是取得您系统MAC地址的步骤:
  1》列举所有的接口卡。
  2》重置每块卡以取得它的正确信息。
  3》查询接口卡,取得MAC地址并生成标准的冒号分隔格式。
  
  下面就是实例源程序。
  netbios.cpp
  
  #include windows.h
  #include stdlib.h
  #include stdio.h
  #include iostream
  #include string
  
  using namespace std;
  #define bzero(thing,sz) memset(thing,0,sz)
  
  bool GetAdapterInfo(int adapter_num, string &mac_addr)
  {
    // 重置网卡,以便我们可以查询
    NCB Ncb;
    memset(&Ncb, 0, sizeof(Ncb));
    Ncb.ncb_command = NCBRESET;
    Ncb.ncb_lana_num = adapter_num;
    if (Netbios(&Ncb) != NRC_GOODRET) {
      mac_addr = "bad (NCBRESET): ";
      mac_addr += string(Ncb.ncb_retcode);
      return false;
    }
  
    // 预备取得接口卡的状态块
    bzero(&Ncb,sizeof(Ncb);
    Ncb.ncb_command = NCBASTAT;
    Ncb.ncb_lana_num = adapter_num;
    strcpy((char *) Ncb.ncb_callname, "*");
    struct ASTAT
    {
      ADAPTER_STATUS adapt;
  
       NAME_BUFFER NameBuff[30];
    } Adapter;
    bzero(&Adapter,sizeof(Adapter));
    Ncb.ncb_buffer = (unsigned char *)&Adapter;
    Ncb.ncb_length = sizeof(Adapter);
  
    // 取得网卡的信息,并且假如网卡正常工作的话,返回标准的冒号分隔格式。
    if (Netbios(&Ncb) == 0)
    {
      char acMAC[18];
      sprintf(acMAC, "%02X:%02X:%02X:%02X:%02X:%02X",
              int (Adapter.adapt.adapter_address[0]),
              int (Adapter.adapt.adapter_address[1]),
              int (Adapter.adapt.adapter_address[2]),
              int (Adapter.adapt.adapter_address[3]),
              int (Adapter.adapt.adapter_address[4]),
              int (Adapter.adapt.adapter_address[5]));
      mac_addr = acMAC;
      return true;
    }
    else
    {
      mac_addr = "bad (NCBASTAT): ";
      mac_addr += string(Ncb.ncb_retcode);
      return false;
    }
  }
  
  int main()
  {
    // 取得网卡列表
    LANA_ENUM AdapterList;
    NCB Ncb;
    memset(&Ncb, 0, sizeof(NCB));
    Ncb.ncb_command = NCBENUM;
    Ncb.ncb_buffer = (unsigned char *)&AdapterList;
    Ncb.ncb_length = sizeof(AdapterList);
    Netbios(&Ncb);
  
    // 取得本地以太网卡的地址
    string mac_addr;
    for (int i = 0; i AdapterList.length - 1; ++i)
    {
      if (GetAdapterInfo(AdapterList.lana[i], mac_addr))
      {
        cout "Adapter " int (AdapterList.lana[i])
                "'s MAC is " mac_addr endl;
      }
      else
      {
        cerr "Failed to get MAC address! Do you" endl;
        cerr "have the NetBIOS protocol installed?" endl;
        break;
      }
    }
  
    return 0;
  }
  
  
  file://---------------------------------------------------------------------------
  
  
  第二种方法-使用COM GUID API
  这种方法使用COM API创建一个GUID(全局唯一标识符)并从那里继续MAC地址。GUID通常用来标识COM组件以及系统中的其他对象。它们是由MAC地址(结合其他东西)计算得来的,表面上MAC地址就包含在其中。我说表面上是因为事实上并没有包含。
  
   我提供这种方法更多的是为了作为反面教材。您也许用这种方法能够得到MAC地址,但有时候您只会得到随机的十六进制数值。
  下面的例子十分简单,无需多讲。我们使用CoCreateGuid创建GUID,并将最后六个字节放入字符串中。它们可能是MAC地址,但并不是必然的。
  
  uuid.cpp
  #include windows.h
  #include iostream
  #include conio.h
  
  using namespace std;
  
  int main()
  {
      cout "MAC address is: ";
  
      // 向COM要求一个UUID。假如机器中有以太网卡,
      // UUID最后的六个字节(Data4的2-7字节)应该是本地以太网卡的MAC地址。
      GUID uuid;
      CoCreateGuid(&uuid);
      // Spit the address out
  &nbs
展开更多 50%)
分享

猜你喜欢

取得系统中网卡MAC地址的三种方法

编程语言 网络编程
取得系统中网卡MAC地址的三种方法

win7修改mac地址的三种方法

电脑网络
win7修改mac地址的三种方法

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

获知对方计算机ip地址的三种方法

电脑入门
获知对方计算机ip地址的三种方法

治疗便秘的三种方法

电脑网络
治疗便秘的三种方法

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

治疗便秘三种方法

电脑网络
治疗便秘三种方法

三种方法疗效好

电脑网络
三种方法疗效好

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

风行影视带你观看不一样的中国达人秀

风行影视带你观看不一样的中国达人秀

13种常用按钮、文本框、表单等CSS样式

13种常用按钮、文本框、表单等CSS样式
下拉加载更多内容 ↓