在实际的应用程序中,经常需要在程序检索整个局域网络,获取局域网络中的计算机名和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
//表示枚举的资源句柄指针
);
(2)WnetEnumResource函数WnetEnumResource函数用于枚举网络资源。语法:
DWORD WnetEnumResource( HANDLE hEnum,LPDWORD lpcCount,LPVOID lpBuffer,LPDWORD lpBufferSize );
WnetEnumResource函数参数说明如表18.4所示。表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{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{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{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);
(3)运行程序,效果如图18.6所示。图18.6获取局域网计算机名称和IP
如下代码在VS2008中编译可顺利通过,但未在局域网上测试结果:
voidCChatDlg::GetNameAndIp(CStringArray& NameArray,CStringArray& IpArray)
{
#include
#pragmacomment(lib,"mpr.lib")
NameArray.RemoveAll();
IpArray.RemoveAll();
structhostent *host;
structin_addr *ptr;
DWORD dwScope = RESOURCE_CONTEXT;
NETRESOURCE *NetResource = NULL;
HANDLE hEnum;
WNetOpenEnum( dwScope, NULL, NULL, NULL, &hEnum );
WSADATA wsaData;
WSAStartup(MAKEWORD(1,1),&wsaData);
if(hEnum)
{
DWORD Count = 0xFFFFFFFF;
DWORD BufferSize = 10240;
LPVOID Buffer =newchar[10240];
WNetEnumResource(hEnum, &Count,Buffer, &BufferSize);
NetResource = (NETRESOURCE*)Buffer;
charszHostName[200];
for(unsignedinti = 0;i
{
if(NetResource->dwUsage == RESOURCEUSAGE_CONTAINER &&
NetResource->dwType == RESOURCETYPE_ANY )
{
if(NetResource->lpRemoteName)
{
CString strFullName = NetResource->lpRemoteName;
if( 0 == strFullName.Left(2).Compare(_T("\\\\")) )
strFullName = strFullName.Right(strFullName.GetLength() - 2);
gethostname(szHostName, strlen(szHostName));
USES_CONVERSION;
char*pchar = strFullName.GetBuffer();
host = gethostbyname(pchar);
if(host == NULL)continue;
ptr = (structin_addr *) host->h_addr_list[0];
inta = ptr->S_un.S_un_b.s_b1;// 211
intb = ptr->S_un.S_un_b.s_b2;// 40
intc = ptr->S_un.S_un_b.s_b3;// 35
intd = ptr->S_un.S_un_b.s_b4;// 76
CString strTemp;
strTemp.Format(_T("%d.%d.%d.%d"),a,b,c,d);
NameArray.Add(strFullName);
IpArray.Add(strTemp);
}
}
}
deleteBuffer;
WNetCloseEnum( hEnum );
}
WSACleanup();
}
voidCChatDlg::OnBnClickedBtnGetip()
{
CStringArray NameArray;
CStringArray IpArray;
GetNameAndIp(NameArray, IpArray);
}