请教如何快速地搜索网段内的所有主机 我想快速搜索网段内的所有主机,注意,我强调的是快速,能否给个例子,[email protected],谢谢。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 在实际的应用程序中,经常需要在程序检索整个局域网络,获取局域网络中的计算机名和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 );WnetOpenEnum函数参数说明如表18.3所示。表18.3 WnetOpenEnum函数参数说明参 数 名 称 参 数 说 明 DwScope 表示网络枚举的范围 DwType 表示枚举的资源类型 DwUsage 表示枚举资源的用法 LpNetResource 用于返回网络资源信息 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。程序设计具体步骤如下。(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);(3)运行程序,效果如图18.6所示。图18.6 获取局域网计算机名称和IP 就是主机扫描,这里有源码,防火墙的话,一般是不会过滤的。不像端口扫描,很容易被防火墙禁掉。 http://download.csdn.net/source/1155041http://www.wangchao.net.cn/bbsdetail_23106.html 谢谢7楼,8楼的,你说的SendARP,我今天也上网找了一下,说ARP搜索挺快的,请问你有没有源代码看看,谢谢 MSDN的SendARP说明中就有例子。 简单的例子 void OnBnClicked() { unsigned char destmac[6] = {0}; unsigned long len = 6; unsigned long ip = inet_addr("192.168.1.1"); if(ip == INADDR_NONE || ip == INADDR_ANY) { MessageBox("输入的IP不合法!", "错误", MB_ICONERROR); return; } for (int i = 1; i < 255; i++) { if(SendARP(((ip & 0x00ffffff) | ((i & 0xff) << 24)), 0, &destmac[0], &len) == NO_ERROR) { CString str; str.Format("IP %s被%02x-%02x-%02x-%02x-%02x-%02x占用!", inet_ntoa(*(in_addr*)&ip), destmac[0], destmac[1], destmac[2], destmac[3], destmac[4], destmac[5]); MessageBox(str); } } } 用UDP协议实现广播通信 补充一下,如果ip不存在时SendARP会等待一段时间,可以通过创建线程的方式来提高速度。例如:#include <stdio.h>#include <windows.h>#include <winsock2.h>#include <iphlpapi.h>#pragma comment (lib, "ws2_32.lib" )#pragma comment (lib, "Iphlpapi.lib")DWORD WINAPI TestThread(LPVOID lParam){ int n = (int)(INT_PTR)lParam << 24; IPAddr ip = inet_addr("192.168.0.0") + n; BYTE mac[8]; ULONG len = sizeof(mac); if (SendARP(ip, 0, (PULONG)mac, &len) == NO_ERROR) { printf("192.168.0.%d : %02X-%02X-%02X-%02X-%02X-%02X\n", n, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } return 0;}void main(){ HANDLE h[255]; for (int i=1; i<255; i++) { h[i] = CreateThread(NULL, 0, TestThread, (PVOID)(INT_PTR)i, 0, NULL); } for (int j=1; j<255; j++) { WaitForSingleObject(h[j], -1); CloseHandle(h[j]); }} 晕,写错了,更正一下:DWORD WINAPI TestThread(LPVOID lParam){ int n = (int)(INT_PTR)lParam; IPAddr ip = inet_addr("192.168.0.0") + (n << 24); BYTE mac[8]; ULONG len = sizeof(mac); if (SendARP(ip, 0, (PULONG)mac, &len) == NO_ERROR) { printf("192.168.0.%d : %02X-%02X-%02X-%02X-%02X-%02X\n", n, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } return 0;} 这个账户不用了,给另外的账户度点分! update 软件更新程序,本机如何进行测试? 关于多线程显示数据 CPtrArray一定要用SetSize初始化吗? 今天在北京找到工作了,大家参考下待遇怎么样 菜鸟请教 请教:关于添加类型数据成员的问题(高分) 怎么在程序实现改变分辨率的功能 过节啦,发红包呀,每人10分,多贴无效 谁知道OnDraw()函数的调用时机与激活方式? WebBrowser控件打开网页,如何屏蔽右键消息 [砖头]惊!高仿!山寨CodeProject!
参 数 说 明
DwScope
表示网络枚举的范围
DwType
表示枚举的资源类型
DwUsage
表示枚举资源的用法
LpNetResource
用于返回网络资源信息
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。程序设计具体步骤如下。(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);(3)运行程序,效果如图18.6所示。图18.6 获取局域网计算机名称和IP
http://download.csdn.net/source/1155041
http://www.wangchao.net.cn/bbsdetail_23106.html
{
unsigned char destmac[6] = {0};
unsigned long len = 6;
unsigned long ip = inet_addr("192.168.1.1");
if(ip == INADDR_NONE || ip == INADDR_ANY)
{
MessageBox("输入的IP不合法!", "错误", MB_ICONERROR);
return;
}
for (int i = 1; i < 255; i++)
{
if(SendARP(((ip & 0x00ffffff) | ((i & 0xff) << 24)), 0, &destmac[0], &len) == NO_ERROR)
{
CString str;
str.Format("IP %s被%02x-%02x-%02x-%02x-%02x-%02x占用!", inet_ntoa(*(in_addr*)&ip), destmac[0], destmac[1], destmac[2], destmac[3], destmac[4], destmac[5]);
MessageBox(str);
}
}
}
#include <stdio.h>
#include <windows.h>
#include <winsock2.h>
#include <iphlpapi.h>
#pragma comment (lib, "ws2_32.lib" )
#pragma comment (lib, "Iphlpapi.lib")DWORD WINAPI TestThread(LPVOID lParam)
{
int n = (int)(INT_PTR)lParam << 24;
IPAddr ip = inet_addr("192.168.0.0") + n;
BYTE mac[8];
ULONG len = sizeof(mac);
if (SendARP(ip, 0, (PULONG)mac, &len) == NO_ERROR)
{
printf("192.168.0.%d : %02X-%02X-%02X-%02X-%02X-%02X\n", n, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
return 0;
}void main()
{
HANDLE h[255];
for (int i=1; i<255; i++)
{
h[i] = CreateThread(NULL, 0, TestThread, (PVOID)(INT_PTR)i, 0, NULL);
}
for (int j=1; j<255; j++)
{
WaitForSingleObject(h[j], -1);
CloseHandle(h[j]);
}
}
DWORD WINAPI TestThread(LPVOID lParam)
{
int n = (int)(INT_PTR)lParam;
IPAddr ip = inet_addr("192.168.0.0") + (n << 24);
BYTE mac[8];
ULONG len = sizeof(mac);
if (SendARP(ip, 0, (PULONG)mac, &len) == NO_ERROR)
{
printf("192.168.0.%d : %02X-%02X-%02X-%02X-%02X-%02X\n", n, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
return 0;
}