VC擷取IP位址和MAC位址程式(轉載)
分類: VC 網絡程式設計 C/C++ 2010-07-27 11:25 6381人閱讀 評論(1) 收藏 舉報 buffer command struct include 程式設計 list
[cpp] view plain copy
- #include <winsock2.h> //該頭檔案定義了Socket程式設計的功能
- #include <stdio.h> //該頭檔案聲明了輸入輸出流函數
- #include <stdlib.h> //該頭檔案定義了一些通用函數
- #include <httpext.h> //該頭檔案支援HTTP請求
- #include <windef.h> //該頭檔案定義了Windows的所有資料基本型态
- #include <Nb30.h> //該頭檔案聲明了netbios的所有的函數
- #pragma comment(lib,"ws2_32.lib") //連接配接ws2_32.lib庫.隻要程式中用到Winsock API 函數,都要用到 Ws2_32.lib
- #pragma comment(lib,"netapi32.lib") //連接配接Netapi32.lib庫,MAC擷取中用到了NetApi32.DLL的功能
- //在Win32平台上的Winsock程式設計都要經過下列的基本步驟:定義變量->獲得Winsock版本->加載Winsock庫->
- //初始化->建立套接字->設定套接字選項->關閉套接字->解除安裝Winsock庫,釋放所有資源。
- void CheckIP(void) //定義checkIP函數,用于取本機的ip位址
- {
- WSADATA wsaData;
- char name[155]; //定義用于存放獲得主機名的變量
- char *ip; //定義IP位址變量
- PHOSTENT hostinfo;
- //調用MAKEWORD()獲得Winsocl版本的正确值,用于下面的加載Winscok庫
- if ( WSAStartup( MAKEWORD(2,0), &wsaData ) == 0 )
- { //加載Winsock庫,如果WSAStartup()函數傳回值為0,說明加載成功,程式可以繼續往下執行
- if( gethostname ( name, sizeof(name)) == 0)
- { //如果成功,将本地主機名存放入由name參數指定的緩沖區中
- if((hostinfo = gethostbyname(name)) != NULL)
- { //這是擷取主機,如果獲得主機名成功的話,将傳回一個指針,指向hostinfo,hostinfo為PHOSTENT型的變量。
- ip = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list);
- //inet_addr()函數把位址串轉換為IP位址
- //調用inet_ntoa()函數,将hostinfo結構變量中的h_addr_list轉化為标準的IP位址(如202.197.11.12.)
- printf(" IP位址: %s/n",ip); //輸出IP位址
- }
- }
- WSACleanup( ); //解除安裝Winsock庫,并釋放所有資源
- }
- }
- //通過WindowsNT/Win2000中内置的NetApi32.DLL的功能來實作的。首先通過發送NCBENUM指令,擷取網卡的
- //數目和每張網卡的内部編号,然後對每個網卡标号發送NCBASTAT指令擷取其MAC位址。
- int getMAC(char * mac) //用NetAPI來擷取網卡MAC位址
- {
- NCB ncb; //定義一個NCB(網絡控制塊)類型的結構體變量ncb
- typedef struct _ASTAT_ //自定義一個結構體_ASTAT_
- {
- ADAPTER_STATUS adapt;
- NAME_BUFFER NameBuff [30];
- }ASTAT, *PASTAT;
- ASTAT Adapter;
- typedef struct _LANA_ENUM //自定義一個結構體_ASTAT_
- {
- UCHAR length;
- UCHAR lana[MAX_LANA]; //存放網卡MAC位址
- }LANA_ENUM;
- LANA_ENUM lana_enum;
- // 取得網卡資訊清單
- UCHAR uRetCode;
- memset(&ncb, 0, sizeof(ncb)); //将已開辟記憶體空間ncb 的值均設為值 0
- memset(&lana_enum, 0, sizeof(lana_enum)); //清空一個結構類型的變量lana_enum,指派為0
- //對結構體變量ncb指派
- ncb.ncb_command = NCBENUM; //統計系統中網卡的數量
- ncb.ncb_buffer = (unsigned char *)&lana_enum; //ncb_buffer成員指向由LANA_ENUM結構填充的緩沖區
- ncb.ncb_length = sizeof(LANA_ENUM);
- //向網卡發送NCBENUM指令,以擷取目前機器的網卡資訊,如有多少個網卡,每個網卡的編号(MAC位址)
- uRetCode = Netbios(&ncb); //調用netbois(ncb)擷取網卡序列号
- if(uRetCode != NRC_GOODRET)
- return uRetCode;
- //對每一個網卡,以其網卡編号為輸入編号,擷取其MAC位址
- for(int lana=0; lana<lana_enum.length; lana++)
- {
- ncb.ncb_command = NCBRESET; //對網卡發送NCBRESET指令,進行初始化
- ncb.ncb_lana_num = lana_enum.lana[lana];
- uRetCode = Netbios(&ncb);
- }
- if(uRetCode != NRC_GOODRET)
- return uRetCode;
- // 準備取得接口卡的狀态塊取得MAC位址
- memset(&ncb, 0, sizeof(ncb));
- ncb.ncb_command = NCBASTAT; //對網卡發送NCBSTAT指令,擷取網卡資訊
- ncb.ncb_lana_num = lana_enum.lana[0]; //指定網卡号,這裡僅僅指定第一塊網卡,通常為有線網卡
- strcpy((char*)ncb.ncb_callname, "*"); //遠端系統名指派為*
- ncb.ncb_buffer = (unsigned char *)&Adapter; //指定傳回的資訊存放的變量
- ncb.ncb_length = sizeof(Adapter);
- //接着發送NCBASTAT指令以擷取網卡的資訊
- uRetCode = Netbios(&ncb);
- // 取得網卡的資訊,并且如果網卡正常工作的話,傳回标準的冒号分隔格式。
- if(uRetCode != NRC_GOODRET)
- return uRetCode;
- //把網卡MAC位址格式轉化為常用的16進制形式,輸出到字元串mac中
- sprintf(mac,"%02X-%02X-%02X-%02X-%02X-%02X",
- Adapter.adapt.adapter_address[0],
- Adapter.adapt.adapter_address[1],
- Adapter.adapt.adapter_address[2],
- Adapter.adapt.adapter_address[3],
- Adapter.adapt.adapter_address[4],
- Adapter.adapt.adapter_address[5]
- );
- return 0;
- }
- int main(void) //主函數,程式的入口
- {
- CheckIP(); //調用CheckIP()函數獲得,輸出IP位址
- char mac[200];
- getMAC(mac); //調用getMAC()函數獲得,輸出MAC位址
- printf(" mac位址 : %s /n",mac);
- return 0;
- }