国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

取得系統(tǒng)中網(wǎng)卡MAC地址的三種方法

2019-11-17 05:01:05
字體:
供稿:網(wǎng)友
做好的程序員一如做人。多看多想或許他山之石可以攻玉,但永遠(yuǎn)不要成為代碼的奴隸。 CKER
原著:Borland
Translated by CKER

第一種方法使用Microsoft的Netbios API。 這是一套通過Winsock提供底層網(wǎng)絡(luò)支持的命令。使用Netbios的最大缺點(diǎn)是您必須在系統(tǒng)中安裝了Netbios服務(wù)(假如您在windows網(wǎng)絡(luò)中啟用了文件共享的話,這就不是問題了)。除此此外,這種方法又快又準(zhǔn)確。

Netbios API只包括了一個(gè)函數(shù),就叫做Netbios。這個(gè)函數(shù)使用網(wǎng)絡(luò)控制塊(network control block)結(jié)構(gòu)作為參數(shù),這個(gè)結(jié)構(gòu)告訴函數(shù)要做什么。結(jié)構(gòu)的定義如下:
  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;



重點(diǎn)在于ncb_command 成員。這個(gè)成員告訴Netbios該作什么。我們使用三個(gè)命令來探測(cè)MAC地址。他們?cè)贛SDN的定義如下:
命令描述:
NCBENUM Windows NT/2000: 列舉系統(tǒng)中網(wǎng)卡的數(shù)量。使用此命令后,ncb_buffer成員指向由LANA_ENUM結(jié)構(gòu)填充的緩沖區(qū)。
NCBENUM 不是標(biāo)準(zhǔn)的 NetBIOS 3.0 命令。

NCBRESET 重置網(wǎng)卡。網(wǎng)卡在接受新的NCB命令之前必須重置。
NCBASTAT 接受本地或遠(yuǎn)程接口卡的狀態(tài)。使用此命令后,ncb_buffer成員指向由ADAPTER_STATUS結(jié)構(gòu)填充的緩沖區(qū),隨后是NAME_BUFFER結(jié)構(gòu)的數(shù)組。

下面就是取得您系統(tǒng)MAC地址的步驟:
1》列舉所有的接口卡。
2》重置每塊卡以取得它的正確信息。
3》查詢接口卡,取得MAC地址并生成標(biāo)準(zhǔn)的冒號(hào)分隔格式。

下面就是實(shí)例源程序。
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)
{
  // 重置網(wǎng)卡,以便我們可以查詢
  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;
  }

  // 預(yù)備取得接口卡的狀態(tài)塊
  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);

  // 取得網(wǎng)卡的信息,并且假如網(wǎng)卡正常工作的話,返回標(biāo)準(zhǔn)的冒號(hào)分隔格式。
  if (Netbios(&Ncb) == 0)
  {
    char acMAC[18];
    s            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()
{
  // 取得網(wǎng)卡列表
  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);

  // 取得本地以太網(wǎng)卡的地址
  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創(chuàng)建一個(gè)GUID(全局唯一標(biāo)識(shí)符)并從那里繼續(xù)MAC地址。GUID通常用來標(biāo)識(shí)COM
組件以及系統(tǒng)中的其他對(duì)象。它們是由MAC地址(結(jié)合其他東西)計(jì)算得來的,表面上MAC地址就包含在其中。我說表面上是因?yàn)槭聦?shí)上并沒有包含。

我提供這種方法更多的是為了作為反面教材。您也許用這種方法能夠得到MAC地址,但有時(shí)候您只會(huì)得到隨機(jī)的十六進(jìn)制數(shù)值。
下面的例子十分簡(jiǎn)單,無需多講。我們使用CoCreateGuid創(chuàng)建GUID,并將最后六個(gè)字節(jié)放入字符串中。它們可能是MAC地址,但并不是必然的。

uuid.cpp
#include <windows.h>
#include <iostream>
#include <conio.h>

using namespace std;

int main()
{
    cout << "MAC address is: ";

    // 向COM要求一個(gè)UUID。假如機(jī)器中有以太網(wǎng)卡,
    // UUID最后的六個(gè)字節(jié)(Data4的2-7字節(jié))應(yīng)該是本地以太網(wǎng)卡的MAC地址。
    GUID uuid;
    CoCreateGuid(&uuid);
    // Spit the address out
&nbs

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 舞阳县| 太仓市| 太保市| 抚顺市| 宣化县| 襄城县| 安义县| 仁怀市| 广昌县| 海南省| 安义县| 栾城县| 耿马| 安阳县| 钦州市| 汨罗市| 丰都县| 祁东县| 南丹县| 宁安市| 姚安县| 延津县| 灵山县| 阿勒泰市| 调兵山市| 罗定市| 南郑县| 乐业县| 丰城市| 顺昌县| 泸州市| 兴仁县| 两当县| 澳门| 普兰店市| 东乡| 响水县| 板桥市| 临邑县| 昌黎县| 永定县|