在實際的應用程序中,經常需要在程序檢索整個局域網絡,獲取局域網絡中的計算機名和IP地址。如果想獲得計算機名主要使用了Windows API函數庫中的WnetOpenEnum、WnetEnumResource和WnetCloseEnum函數,而在使用這些函數之前,需要初始化向程序中導入mpr.lib庫和頭文件winnetwk.h;如果想獲得計算機IP主要使用了gethostbyname函數,在使用該函數之前,需要導入ws2_32.lib庫和頭文件afxsock.h。其中各函數的介紹如下:
(1)WnetOpenEnum函數
WnetOpenEnum函數用於啓動對網絡資源進行枚舉的過程。
語法:
DWORD WnetOpenEnum( DWORD dwScope,DWORD dwType,DWORD dwUsage, LPNETRESOURCE lpNetResource,LPHANDLE lphEnum ); |
表18.3 WnetOpenEnum函數參數說明
參 數 名 稱 參 數 說 明
DwScope 表示網絡枚舉的範圍
DwType 表示枚舉的資源類型
DwUsage 表示枚舉資源的用法
LpNetResource 用於返回網絡資源信息
LphEnum 表示枚舉的資源句柄指針
(2)WnetEnumResource函數
WnetEnumResource函數用於枚舉網絡資源。
語法:
DWORD WnetEnumResource( HANDLE hEnum,LPDWORD lpcCount,LPVOID lpBuffer ,LPDWORD lpBufferSize ); |
表18.4 WnetEnumResource函數參數說明
參 數 名 稱 參 數 說 明
hEnum 由WnetOpenEnum函數的參數lphEnum傳入,表示枚舉的資源句柄
lpcCount 用來決定獲取的資源數目最大值
lpBuffer 向枚舉結果存放的緩衝區地址
lpBufferSize 指向枚舉結果存儲緩衝區大小的變量地址
(3)WnetCloseEnum函數
WnetCloseEnum函數用於結束一次枚舉操作。
語法:
DWORD WnetCloseEnum( HANDLE hEnum ); |
hEnum:由WnetOpenEnum函數的參數lphEnum傳入。
(4)gethostbyname函數
gethostbyname函數能夠通過計算機的名稱返回其網絡信息,這個信息中包括IP地址。
語法:
struct hostent FAR * gethostbyname ( const char FAR * name ); |
name:包含計算機名稱的字符串。
下面以一個具體實例介紹如何獲得網絡計算的名稱和IP。程序設計具體步驟如下。
ch1803實例位置:mr/18/sl/03
(1)新建一個基於對話框的應用程序,設計對話框資源如圖18.5所示。
圖18.5 主對話框資源設計窗口
(2)在對話框的OnInitDialog方法中獲取網絡中的計算機和IP。
//初始化網絡庫 WSADATA wsd; WSAStartup(MAKEWORD(2,2),&wsd); //設置表格風格 m_grid.SetExtendedStyle(LVS_EX_FLATSB |LVS_EX_FULLROWSELECT |LVS_EX_HEADERDRAGDROP |LVS_EX_ONECLICKACTIVATE |LVS_EX_GRIDLINES); //向表格中插入列 m_grid.InsertColumn(0,"計算機名",LVCFMT_LEFT,200,0); m_grid.InsertColumn(1,"IP地址",LVCFMT_LEFT,200,0); DWORD Count=0xFFFFFFFF,Bufsize=4096,Res; NETRESOURCE* nRes; NETRESOURCE* nRes1; NETRESOURCE* nRes2; HANDLE lphEnum; LPVOID Buf = new char[4096]; LPVOID Buf1 = new char[4096]; LPVOID Buf2 = new char[4096]; //打開列舉的網絡資源 Res = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, RESOURCEUSAGE_CONTAINER,NULL,&lphEnum); //獲取列舉的網絡資源信息 Res=WNetEnumResource(lphEnum,&Count,Buf,&Bufsize); nRes=(NETRESOURCE*)Buf; for(DWORD n=0;n<Count;n++,nRes++) { DWORD Count1=0xFFFFFFFF; Res = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, RESOURCEUSAGE_CONTAINER,nRes,&lphEnum); Res=WNetEnumResource(lphEnum,&Count1,Buf1,&Bufsize); nRes1=(NETRESOURCE*)Buf1; for(DWORD i=0;i<Count1;i++,nRes1++) { DWORD Count2=0xFFFFFFFF; Res = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, RESOURCEUSAGE_CONTAINER,nRes1,&lphEnum); Res=WNetEnumResource(lphEnum,&Count2,Buf2,&Bufsize); nRes2=(NETRESOURCE*)Buf2; for(DWORD j=0;j<Count2;j++,nRes2++) { m_grid.InsertItem(j,0); CString sName=nRes2->lpRemoteName; sName=sName.Right(sName.GetLength()-2); m_grid.SetItemText(j,0,sName); CString str=""; struct hostent * pHost; pHost = gethostbyname(sName); if(pHost==NULL) { m_grid.SetItemText(j,1,"無法獲得IP地址"); } else { for(int n=0;n<4;n++) { CString addr; if(n > 0) { str += "."; } addr.Format("%u",(unsigned int)((unsigned char*)pHost->h_addr_list[0])[n]); str += addr; } m_grid.SetItemText(j,1,str); } } } } delete Buf; delete Buf1; delete Buf2; WNetCloseEnum(lphEnum); |
圖18.6 獲取局域網計算機名稱和IP