读书人

获取局域网内在线的所有主机名及其IP地

发布时间: 2012-02-01 16:58:19 作者: rapoo

获取局域网内在线的所有主机名及其IP地址
获取局域网内在线的所有主机名及其IP地址
Author:swun911
blog.sina.com.cn/swun
偶想搜索到局域网内所有在线的主机并获得其地址,使用了API的WNetEnumResource和gethostbyname。实现倒是实现了,可就是特别的慢,请指教。不知道各位高手有什么妙招,请赐教!
My Emai:56557833@qq.com
我实现该目的部分的代码如下:
//**************************************************************************************
//获取主机名
do
{
EnumLocal = (LPNETRESOURCE) GlobalAlloc( GPTR, dwBuffer ) ;
dwResult = WNetEnumResource(hEnum,&dwEntries,EnumLocal,&dwBuffer);
if( dwResult == NO_ERROR )
{
int kyy=0;
for( register DWORD i = 0 ; i < dwEntries ; i++ )
{
CString Enumname;
Enumname = EnumLocal[i].lpRemoteName;
Enumname += " ";
Enumname +=EnumLocal[i].lpLocalName;
Enumname += " ";
Enumname +=EnumLocal[i].lpComment;
CString Filtrate = Enumname.Left(1);
if(Filtrate== '\\ ')
{
CString Inputname,IPAddress;
Inputname=Enumname.Right(Enumname.GetLength()-2);//去掉 "\\ "
Inputname=Inputname.SpanExcluding( " ");//去掉空格及其以后的部分
GetIPAddress(Inputname,IPAddress);
userinfo[kyy].h_name=Inputname;
userinfo[kyy].h_IPadd=IPAddress;
userinfo[kyy+1].h_name= "xxx ";
kyy++;
}
}
}
} while( dwResult != ERROR_NO_MORE_ITEMS );
//****************************************************************************
//IP地址
GetIPAddress(CString &HostName, CString &IPAddress)
{
struct hostent FAR *pIPHostEnt=gethostbyname(HostName);
if (pIPHostEnt==NULL)
{
IPAddress=_T( "获取地址失败! ");
return GetLastError();
}

LPSTR IPAddr=pIPHostEnt-> h_addr_list[0];
if(IPAddr)
{
struct in_addr inAddr;
memmove(&inAddr,IPAddr,4);
IPAddress=inet_ntoa(inAddr);
if(IPAddress.IsEmpty())
{
IPAddress=_T( "没有取得IP ");
AfxMessageBox(IPAddress);
}
}
return 0;
}

[解决办法]
WSADATA wsaData;


SOCKET sockListener;
SOCKADDR_IN saUdpCli,saUdpServ;
BOOL fBroadcast = TRUE;

char sendBuff[40]= //查询包内容
{
'\x30 ', '\x26 ', '\x02 ', '\x01 ', '\x00 ',
'\x04 ', '\x06 ', '\x70 ', '\x75 ', '\x62 ',
'\x6c ', '\x69 ', '\x63 ', '\xa0 ', '\x19 ',
'\x02 ', '\x01 ', '\x03 ', '\x02 ', '\x01 ',
'\x00 ', '\x02 ', '\x01 ', '\x00 ', '\x30 ',
'\x0e ', '\x30 ', '\x0c ', '\x06 ', '\x08 ',
'\x2b ', '\x06 ', '\x01 ', '\x02 ', '\x01 ',
'\x01 ', '\x01 ', '\x00 ', '\x05 ', '\x00 '
};
char recvBuff[600];
int nSize,err,timeoutnum = 1;;
ULONG HostIpAddr;
int rv;
int ncount=0;

if(WSAStartup(MAKEWORD( 2, 2),&wsaData)!=0)
{
printf( "Winsocket start error!\n ");
return;
}

sockListener=socket(AF_INET,SOCK_DGRAM,0);
err = setsockopt ( sockListener,
SOL_SOCKET,
SO_BROADCAST,
(CHAR *)&fBroadcast,
sizeof ( BOOL ));
if ( SOCKET_ERROR == err ) return ;

int TimeOut=3000;

err = setsockopt ( sockListener,
SOL_SOCKET,
SO_RCVTIMEO,
(CHAR *) &TimeOut,
sizeof (TimeOut)
);
if ( SOCKET_ERROR == err ) return ;

saUdpCli.sin_family = AF_INET;
saUdpCli.sin_port = htons(0);
saUdpCli.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind( sockListener, (SOCKADDR *)&saUdpCli, sizeof(SOCKADDR_IN))!=0)
{
printf( "Can 't bind socket to local port!Program stop.\n ");
return;
}

err = gethostname(recvBuff,sizeof(recvBuff));
if ( SOCKET_ERROR == err )
return ;

struct hostent *hp = gethostbyname(recvBuff);
if (!hp) return ;

saUdpServ.sin_family = AF_INET;

memcpy(&(saUdpServ.sin_addr),hp-> h_addr,hp-> h_length);
HostIpAddr=ntohl(saUdpServ.sin_addr.s_addr);

saUdpServ.sin_addr.s_addr = htonl ( INADDR_BROADCAST );
saUdpServ.sin_port = htons (SNMP_PORT);
nSize = sizeof ( SOCKADDR_IN );
if((rv = sendto ( sockListener,
sendBuff,
sizeof(sendBuff),0,
(SOCKADDR *) &saUdpServ,
sizeof ( SOCKADDR_IN )))==SOCKET_ERROR)
{
printf( "Send error!\n ");
closesocket(sockListener);
return;
}
printf( "Send successful!\n ");
do // waiting to receive
{
if((rv=recvfrom ( sockListener,
recvBuff,sizeof(recvBuff),0,
(SOCKADDR *) &saUdpCli,&nSize))==SOCKET_ERROR)
{
if(WSAGetLastError()==WSAETIMEDOUT)
{
if (timeoutnum > 1 ) //Wait for 1 minute.
break;
else
timeoutnum++;
TRACE( "Error \n ");

}
}
else
{
CString Ip(inet_ntoa ( saUdpCli.sin_addr ));
m_pIpList-> AddTail(Ip);
TRACE( "\t IP Adress-> %s \n ",Ip);
}

}while(TRUE);
closesocket(sockListener);

[解决办法]
用 SendArp() 这个函数 获得0~255 他们的mac地址
得到了就是在线 得不到就是没在
开100个线程 处理0~99 发送后等待1秒 得到了就说明在线
然后1秒后处理100~199..如此循环
最多2~3秒就ok了

读书人网 >VC/MFC

热点推荐