我想快速搜索所有主机,我已经试过以下方法,注意,我强调的是快速
1.用ping,当然可以,但是如果要在程序中实现不大合理,而且我觉得速度也快不到哪里去
2.用winpcap发送arp请求包可以获得,但是获取时间不确定,而且获取速度不算太快
3.用SendARP函数,对于需要扫描255个主机时简直太慢了,不能忍受,感觉程序都无法响应了。于是我尝试着开255个线程分别调用SendARP函数,结果发现大多数SendArp都调用失败,错误值是31。不知道为什么
4.看到网上有人使用先枚举网络资源,再获取主机信息,然后有主机名获取IP,最后由IP获取MAC的方法,我觉得速度也快不到哪里去(这个没有具体试过)
1.用ping,当然可以,但是如果要在程序中实现不大合理,而且我觉得速度也快不到哪里去
2.用winpcap发送arp请求包可以获得,但是获取时间不确定,而且获取速度不算太快
3.用SendARP函数,对于需要扫描255个主机时简直太慢了,不能忍受,感觉程序都无法响应了。于是我尝试着开255个线程分别调用SendARP函数,结果发现大多数SendArp都调用失败,错误值是31。不知道为什么
4.看到网上有人使用先枚举网络资源,再获取主机信息,然后有主机名获取IP,最后由IP获取MAC的方法,我觉得速度也快不到哪里去(这个没有具体试过)
解决方案 »
- mfc opengl 重绘线程问题,欢迎讨论和指教
- 驱动中如何调用常规API?
- 怎么判断一个文件是否正在处于被写状态中?
- 怎样设置日历控件的多月显示(CMonthCalCtrl)
- VC++ 换行符是什么?
- 那里有读写ini 文件的比较好的类?
- 如何获取IE版本号
- 纳闷了,哪里出错了?LPCTSTR和CString不是通用的吗?
- 连接数据库失败,求帮助
- 高手们自以为不屑的问题,可是又有哪位高人弄清它了!
- 有关vc技术内幕这本书!
- 怎样得到CTreeCtrl中当前选择的条目的TEXT呀!用m_Tree.GetItemText(m_Tree.GetSelectedItem())在OnSelchangingTree事件中总是得到上次选
NETRESOURCE *NetResource = NULL;
HANDLE hEnum;
WNetOpenEnum( dwScope, NULL, NULL,
NULL, &hEnum );
if ( hEnum )
{
DWORD Count = 0xFFFFFFFF;
DWORD BufferSize = 2048;
LPVOID Buffer = new char[2048];
WNetEnumResource( hEnum, &Count,
Buffer, &BufferSize );
NetResource = (NETRESOURCE*)Buffer; char szHostName[200];
unsigned int i; for ( i = 0;i < BufferSize/sizeof(NETRESOURCE);i++, NetResource++ )
{
if ( NetResource->dwUsage ==RESOURCEUSAGE_CONTAINER &&NetResource->dwType ==RESOURCETYPE_ANY )
{
if ( NetResource->lpRemoteName )
{
CString strFullName =NetResource->lpRemoteName;
if ( 0 ==strFullName.Left(2).Compare("\\\\") )
strFullName =strFullName.Right(strFullName.GetLength()-2);
gethostname( szHostName,strlen( szHostName ) );
host = gethostbyname(strFullName);
if(host == NULL) continue;
strTemp.Format("%s",strFullName);
m_List.InsertItem(i,strTemp,0); // 获得地址添加到列表
}
}
}
delete Buffer;
WNetCloseEnum( hEnum );
www.codeproject.com/treectrl/pathpicker.asp
另外你能告诉我为什么多线程调用SendARP就会失败么?谢谢叻
我也知道网上邻居是采用的netenum,但是难道不觉得网上邻居打开很慢么?!我就是觉得太慢了啊,所以就想问有没有快一点的方法,呵呵
我在多线程中调用失败啊,错误值都是31,不知道为什么,能指点一下么?!
线程函数大概如下
DWORD WINAPI GetMacByIP(LPVOID lParam)
{
char * szIp=(char *)lParam;
ULONG szMac[2];
ULONG puMacLen=6;
int ret;
ret=SendARP(szIp,0,szMac,&puMacLen);
....
return ret;
}
不知道为什么
}
ret=SendARP(inet_addr(szIp),0,szMac,&puMacLen);不知道为什么,如果循环调用,成功,只不过速度很慢如果开多线程,很多调用都失败,返回值都是31
DWORD WINAPI ArpThread(LPVOID lParam)
{
char * szIp=(char *)lParam;
ULONG pMac[2];
ULONG pulen=6;
int ret;
if ((ret=SendARP(inet_addr(szIp),0,pMac,&pulen))==0)
{
PBYTE pbyte=(PBYTE)pMac;
for (int i=0;i<5;i++)
{
TRACE("%02X-",pbyte[i]);
}
TRACE("%02X",pbyte[5]);
}
else
{
TRACE("SendARP Error %d",ret);
}
return 0;
}开多线程调用
void CTestArpDlg::OnButton1()
{
// TODO: Add your control notification handler code here
HANDLE hthread[255];
CString IpSuffix="192.168.10.";
CString strIp;
for (int i=0;i<255;i++)
{
strIp.Format("%d",i+1);
strIp=IpSuffix+strIp;
hthread[i]=CreateThread(NULL,0,ArpThread,strIp.GetBuffer(0),0,NULL);
}
WaitForMultipleObjects(255,hthread,TRUE,INFINITE);}
BYTE bs[50]={0x0,0x00,0x0,0x10,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x43,0x4b,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x0,0x0,0x21,0x0,0x1};
HANDLE wait_handle;m_UDPSocket.SendTo((void*)bs,50,destPORT,m_strIP,0);//向指定的ip发数据报
WaitForSingleObject(
wait_handle, // 等待事件的句柄
nWait // 超时
);
ResetEvent(wait_handle);//将事件重新置回非触发状态void CNBTSTATDlg::OnReceive()
{
BYTE Buf[500];
CString str,strIP,strHost,strHex,strMac,Host,Group,User;
UINT dport;
m_UDPSocket.ReceiveFrom(Buf,500,strIP,dport,0);//接收数据
//如果接收到的ip为空或者与原来接收到的ip相同,则返回
if(strIP==(char)NULL||strIP==strOldIP)return;
strOldIP=strIP;
int index=m_ListView.InsertItem(0,strIP);//将ip插入ListView
strHost=""; //机器名字
strHex="";//MAC地址
User="?";//
Host="\\";
int tem=0,num=0;
bool bAdd=true;
//根据数据报规则取出相应的信息
for(i=57;i<500;i++) //57-72
{
if(Buf[i]==0xcc)break;
if(Buf[i]==0x20)bAdd=false;
if(bAdd)
{
str.Format("%c",Buf[i]);
if(Buf[i]>=' ')strHost+=str; str.Format("%02x.",Buf[i]);
strHex+=str;
} if((++tem)%18==0)
{
bAdd=true;
strHost.TrimRight((char)NULL);
if(strHost=="")
{
strMac.Delete(17,strMac.GetLength()-17);
m_ListView.SetItem(index,4,LVIF_TEXT,strMac, 0, 0, 0,0);
break;
}
if(num==0&&strHost!="")
{
m_ListView.SetItem(index,2,LVIF_TEXT,strHost, 0, 0, 0,0);
Host=strHost;
num++;
}
else
{
if(Host!=strHost&&num==1&&strHost!="")
{
m_ListView.SetItem(index,1,LVIF_TEXT,strHost, 0, 0, 0,0);
Group=strHost;
num++;
}
else
{
if(strHost!=Host&&strHost!=Group&&num==2&&strHost!="")
{
User=strHost;
if(User!="__MSBROWSE__")
{
m_ListView.SetItem(index,3,LVIF_TEXT,User, 0, 0, 0,0);
num++;
}
}
} }
strMac=strHex;
strHost="";
strHex="";
}
}
//触发事件,导致线程函数的继续执行
SetEvent(wait_handle);
}
局域网内,我都用此方法,一个字:快,基本上10ns内就可能得到反馈信息,极少出现100毫秒以上才反馈的(未遇到过)
你可能调整几微秒发送一个包都可以啊
不是发送包的速度,这个很好控制。关键是处理回送的arp应答包很伤脑筋啊!
关键如果要保证所有回送的arp包能够收到,肯定时间要长一点啊,因为是开线程处理回送的包,只有保证线程有足够的cpu时间,才可能收到所有包。比如,现在机器上现在正在运行一个高优先级,大计算量的线程,那么很可能我的线程得到运行的机会很少,所以只有设置足够长的时间才能保证包都收到并被处理。
你提供的代码只是枚举和我同一个工作组的主机吗?我运行以后怎么只能得到和我同一工作组的主机,而得不到其它主机啊!怎么回事呢
"关键如果要保证所有回送的arp包能够收到,肯定时间要长一点啊,因为是开线程处理回送的包,只有保证线程有足够的cpu时间,才可能收到所有包。比如,现在机器上现在正在运行一个高优先级,大计算量的线程,那么很可能我的线程得到运行的机会很少,所以只有设置足够长的时间才能保证包都收到并被处理。"
如果你是这么考虑的话,任何扫描都不可能快速的,你说呢?
但是其他方法就比较好控制一点,比如说SendARP,可能也会遇到上面的情况,但是它具有确定性,一旦它调用返回的时候,就可以得到mac地址,即使时间再长,但是这个时间是确定的,我是这个意思,就是想知道一个在时间上具有确定性,并且时间相对较短的方法,呵呵
我就写过这么个程序,扫描时对系统性能没什么影响
#include <iphlpapi.h>
#include <windows.h>
#include <winsock2.h>
#include <windowsx.h>
#pragma hdrstop#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"typedef struct _setup_info
{
PIP_ADAPTER_INFO pAdInfo;
DWORD AdapIndex;
}SETUP_INFO,*PSETUP_INFO;TForm1 *Form1;
SETUP_INFO SetupInfo;//---------------------------------------------------------------------------AnsiString __stdcall sg(AnsiString str,int n)
{
int l,i;
AnsiString qq(str);
l=qq.Length();
AnsiString p(str);
char a[]="\r\n";
int j,k=0;
for(j=1;j< l;j++)
{
i=1;
while(qq[j]!=a[0] && qq[j+1]!=a[1])
{
p[i++]=qq[j];
j++;
}
k++;
if((k-1)==n)
break;
}
p[i]=' ';p[i+1]=' ';
return (p);
}//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------BOOL FormatMACStr(ULONG *pMacAddr,char *szMAC)
{
if(pMacAddr[0]==pMacAddr[1])return FALSE;
return TRUE;
}//----------------------------------------------------------------------------DWORD WINAPI EnumActiveHost(IPAddr ipAddr)
{
char szMAC[18]="";
char szComputerName[256]="";
in_addr inaddr;
ULONG pMacAddr[2],ulLen=6;
ulLen=6;
FillMemory(pMacAddr,sizeof(pMacAddr),0xff);
SendARP(ipAddr,0,pMacAddr,&ulLen);
inaddr.S_un.S_addr=ipAddr;
if(FormatMACStr(pMacAddr,szMAC))
{
TListItem *ListItem=Form1->ListView1->Items->Add();
ListItem->Caption=inet_ntoa(inaddr);
ListItem->SubItems->Add(szMAC);
ListItem->SubItems->Add(szComputerName);
}
return 0;
}//------------------------------------------------------------------DWORD ScanActiveHost(LPVOID lpParameter)
{
DWORD ThreadId;
HANDLE hThread[255];
IPAddr ipAddr=inet_addr("192.168.253.0");
FlushIpNetTable(SetupInfo.AdapIndex);
Form1->StatusBar1->Panels->Items[1]->Text=" 正在扫描...";
Form1->ListView1->Items->Clear();
for(int i=0;i<255;i++)
{
Form1->ProgressBar1->StepBy(1);
ipAddr=htonl((htonl(ipAddr)+1));
hThread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)EnumActiveHost,(LPVOID)ipAddr,0,&ThreadId);
}
WaitForMultipleObjects(255,hThread,TRUE,INFINITE);
for(int i=0;i<255;i++)
{
CloseHandle(hThread[i]);
}
Form1->StatusBar1->Panels->Items[1]->Text=" 扫描结束";
Form1->ProgressBar1->Position=0;
Sleep(1000);
Form1->StatusBar1->Panels->Items[1]->Text=" 共 "+IntToStr(Form1->ListView1->Items->Count)+" 台活动主机";
Form1->ToolButton1->Enabled=TRUE;
Form1->ToolButton2->Enabled=TRUE;
return TRUE;
}//------------------------------------------------------------------DWORD EnumAdapters(HWND hCombo)
{
int comboindex=0;
PIP_ADAPTER_INFO pTemp;
ULONG IfIndex;
HMODULE hModule=LoadLibrary("iphlpapi.dll");
if(hModule==NULL)
return FALSE;
try{
GetAdaptersInfo(NULL,&IfIndex);
SetupInfo.pAdInfo=pTemp=(PIP_ADAPTER_INFO)VirtualAlloc(NULL,IfIndex,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
GetAdaptersInfo(pTemp,&IfIndex);
}catch(Exception &exception)
{
Application->ShowException(&exception);
}
while(pTemp)
{
ComboBox_AddString(hCombo,pTemp->Description);
ComboBox_SetItemData(hCombo,comboindex,pTemp);
pTemp=pTemp->Next;comboindex++;
}return TRUE;
}//------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
EnumAdapters(Form1->ComboBox1->Handle);
ComboBox_SetCurSel(Form1->ComboBox1->Handle,0);
}
//---------------------------------------------------------------------------void __fastcall TForm1::ToolButton2Click(TObject *Sender)
{
HANDLE hFile;
char szPath[MAX_PATH];
AnsiString String;
DWORD nobw;
GetCurrentDirectory(MAX_PATH,szPath);
Form1->SaveDialog1->InitialDir=szPath;
if(!Form1->SaveDialog1->Execute())return;
hFile=CreateFile(SaveDialog1->FileName.c_str(),FILE_ALL_ACCESS,FILE_SHARE_READ,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile==INVALID_HANDLE_VALUE)
{
if(MessageBox(Form1->Handle,"文件已存在,是否要替换?","提示",MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2)==IDYES)
hFile=CreateFile(SaveDialog1->FileName.c_str(),FILE_WRITE_DATA,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
else return;
}//if(hFile==INVALID_HANDLE_VALUE)ShowMessage(IntToStr(GetLastError()));
for(int i=0;i<ListView1->Items->Count;i++)
{
String=String+ListView1->Items->Item[i]->Caption+"\t"+sg(ListView1->Items->Item[i]->SubItems->Text,0);
}
WriteFile(hFile,String.c_str(),String.Length(),&nobw,NULL);
CloseHandle(hFile);
}
//---------------------------------------------------------------------------void __fastcall TForm1::ToolButton1Click(TObject *Sender)
{
DWORD ThreadId;
CloseHandle(CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ScanActiveHost,(LPVOID)NULL,0,&ThreadId));
ToolButton1->Enabled=FALSE;
ToolButton2->Enabled=FALSE;
}
//---------------------------------------------------------------------------
for(int i=0;i<255;i++)
{
Form1->ProgressBar1->StepBy(1);
ipAddr=htonl((htonl(ipAddr)+1));
hThread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)EnumActiveHost,(LPVOID)ipAddr,0,&ThreadId);
}
WaitForMultipleObjects(255,hThread,TRUE,INFINITE);
for(int i=0;i<255;i++)
{
CloseHandle(hThread[i]);
}
Form1->StatusBar1->Panels->Items[1]->Text=" 扫描结束";
Form1->ProgressBar1->Position=0;
Sleep(1000);
不过也是忘记了WaitForMultipleObjects(255,hthread,TRUE,INFINITE);只能等待64个对象,呵呵,不知道是不是这个引起错误了,我马上试试!
另外,你说的
多线程呀,我写过程序的,没有出错啊,在开启线程之间Sleep以下就好了
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
但是我看你程序里面开启线程之间并没有Sleep啊,而是开启所有线程,并且线程结束了以后才Sleep(1000)啊,究竟是怎么回事。另外,调用Sleep和不调用Sleep有区别么??
//全局变量
typedef struct ipmac
{
char szIp[16];
char szMac[6];}IPMAC;
IPMAC host[255];
int k=0;
CRITICAL_SECTION cs;
/*线程函数,用来查询IP对应的MAC地址*/
DWORD WINAPI ArpThread(LPVOID lParam)
{
char * szIp=(char *)lParam;
ULONG pMac[2];
ULONG pulen=6;
int ret;
TRACE(szIp);
if ((ret=SendARP(inet_addr(szIp),0,pMac,&pulen))==0)
{
EnterCriticalSection(&cs); //多线程同步,呵呵:0
strcpy(host[k].szIp,szIp);
PBYTE pbyte=(PBYTE)pMac;
for (int i=0;i<5;i++)
{
host[k].szMac[i]=pbyte[i];
TRACE("%02X-",pbyte[i]);
}
TRACE("%02X",pbyte[5]);
host[k].szMac[5]=pbyte[5];
k++;
LeaveCriticalSection(&cs);
}
else
{
TRACE("SendARP Error %d",ret);
}
return 0;
}/*枚举局域网内所有主机,并将IP/MAC对插入ListBox中显示*/
void CTestArpDlg::OnButton1()
{
// TODO: Add your control notification handler code here
HANDLE hthread[254];
CString IpSuffix="192.168.10.";
CString strIp[254];
InitializeCriticalSection(&cs);
for (int i=0;i<254;i++)
{
strIp[i].Format("%d",i+1);
strIp[i]=IpSuffix+strIp[i];
hthread[i]=CreateThread(NULL,0,ArpThread,strIp[i].GetBuffer(0),0,NULL);
}
/*呵呵,因为一次只能等待 64个内核对象,所以只有分几次了*/
/*当然也可以用循环了*/
WaitForMultipleObjects(64,hthread,TRUE,INFINITE);
WaitForMultipleObjects(64,&hthread[64],TRUE,INFINITE);
WaitForMultipleObjects(64,&hthread[128],TRUE,INFINITE);
WaitForMultipleObjects(62,&hthread[192],TRUE,INFINITE);
DeleteCriticalSection(&cs);
CString temp;
for (i=0;i<k;i++)
{
PBYTE pmac=(PBYTE)host[i].szMac;
temp.Format("%s(%02x-%02x-%02x-%02x-%02x-%02x)",host[i].szIp,pmac[0],pmac[1],pmac[2],pmac[3],pmac[4],pmac[5]);
m_list.AddString(temp);
}
}
"
列举网络上所有资源http://www.ittide.com/document/source/netware/network.zip
"
使用它的程序,除了自己工作组内的主机外,还可以列出自己工作组之外的主机,但是还是不全。所以还是建议大家用多线程SendARP方法,速度快,而且枚举的主机全,呵呵,特别推荐!呵呵,好,问题解决了,如果大家没有什么问题,我就结贴了!
#include <iphlpapi.h>
#include <windows.h>
#include <winsock2.h>
#include <windowsx.h>
#pragma hdrstop#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"typedef struct _setup_info
{
PIP_ADAPTER_INFO pAdInfo;
DWORD AdapIndex;
}SETUP_INFO,*PSETUP_INFO;TForm1 *Form1;
SETUP_INFO SetupInfo;
WSADATA wsadata;//---------------------------------------------------------------------------AnsiString __stdcall sg(AnsiString str,int n) //保存扫描列表所用到的格式化字符串的函数
{
int l,i;
AnsiString qq(str);
l=qq.Length();
AnsiString p(str);
char a[]="\r\n";
int j,k=0;
for(j=1;j< l;j++)
{
i=1;
while(qq[j]!=a[0] && qq[j+1]!=a[1])
{
p[i++]=qq[j];
j++;
}
k++;
if((k-1)==n)
break;
}
p[i]=' ';p[i+1]=' ';
return (p);
}//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------int GetHostNumber(IPAddr *lpAddr) //根据子网掩码得到以太网的主机容纳数目
{
//*lpAddr=inet_addr("192.168.253.0");
IPAddr ipaddr,maskaddr;
HWND hWnd=Form1->ComboBox1->Handle;
ipaddr=inet_addr(((PIP_ADAPTER_INFO)ComboBox_GetItemData(hWnd,ComboBox_GetCurSel(hWnd)))->IpAddressList.IpAddress.String);
maskaddr=inet_addr(((PIP_ADAPTER_INFO)ComboBox_GetItemData(hWnd,ComboBox_GetCurSel(hWnd)))->IpAddressList.IpMask.String);
*lpAddr=maskaddr&ipaddr;
return htonl(~maskaddr)-1;
}//---------------------------------------------------------------------------void GetRemoteComputerName(IPAddr ipAddr,char *szComputerName) //根据IP地址得到计算机名
{
struct hostent* pHost=gethostbyaddr((char*)&ipAddr,4,AF_INET);
if(pHost!=NULL)
lstrcpy(szComputerName,pHost->h_name);
}//---------------------------------------------------------------------------BOOL FormatMACStr(ULONG *pMacAddr,char *szMAC)
{
if(pMacAddr[0]==pMacAddr[1])return FALSE;
for(int i=0;i<6;i++)
{
wsprintf(szMAC+i*3,"%02X",((BYTE *)pMacAddr)[i]);
szMAC[i*3+2]='-';
}szMAC[17]='\0';
return TRUE;
}//----------------------------------------------------------------------------DWORD WINAPI EnumActiveHost(IPAddr ipAddr)
{
char szMAC[18]="";
char szComputerName[256]="";
in_addr inaddr;
ULONG pMacAddr[2],ulLen=6;
FillMemory(pMacAddr,sizeof(pMacAddr),0xff);
SendARP(ipAddr,0,pMacAddr,&ulLen);
inaddr.S_un.S_addr=ipAddr;
if(FormatMACStr(pMacAddr,szMAC))
{
GetRemoteComputerName(ipAddr,szComputerName);
TListItem *ListItem=Form1->ListView1->Items->Add();
ListItem->Caption=inet_ntoa(inaddr);
ListItem->SubItems->Add(szMAC);
ListItem->SubItems->Add(szComputerName);
}return 0;
}//------------------------------------------------------------------DWORD ScanActiveHost(LPVOID lpParameter)
{
DWORD ThreadId;
int hostnum;
HANDLE *hThread;
IPAddr ipAddr;
hostnum=GetHostNumber(&ipAddr);
hThread=(HANDLE *)VirtualAlloc(NULL,4*hostnum,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
FlushIpNetTable(SetupInfo.AdapIndex);
Form1->StatusBar1->Panels->Items[1]->Text=" 正在扫描...";
Form1->ListView1->Items->Clear();
for(int i=0;i<hostnum;i++)
{
Sleep(10);
Form1->ProgressBar1->StepBy(1);
ipAddr=htonl((htonl(ipAddr)+1));
hThread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)EnumActiveHost,(LPVOID)ipAddr,0,&ThreadId);
}//MAXIMUM_WAIT_OBJECTS
for(int i=0;i<=hostnum/MAXIMUM_WAIT_OBJECTS;i++)
WaitForMultipleObjects(i==hostnum/MAXIMUM_WAIT_OBJECTS?MAXIMUM_WAIT_OBJECTS:hostnum%MAXIMUM_WAIT_OBJECTS,hThread+i*MAXIMUM_WAIT_OBJECTS,TRUE,INFINITE);
for(int i=0;i<hostnum;i++)
CloseHandle(hThread[i]);
Form1->StatusBar1->Panels->Items[1]->Text=" 扫描结束";
Form1->ProgressBar1->Position=0;
Sleep(1000);
Form1->StatusBar1->Panels->Items[1]->Text=" 共 "+IntToStr(Form1->ListView1->Items->Count)+" 台活动主机";
Form1->ToolButton1->Enabled=TRUE;
Form1->ToolButton2->Enabled=TRUE;
VirtualFree(hThread,4*hostnum,MEM_DECOMMIT|MEM_RELEASE);
return TRUE;
}//------------------------------------------------------------------DWORD EnumAdapters(HWND hCombo)
{
int comboindex=0;
PIP_ADAPTER_INFO pTemp;
ULONG IfIndex;
try{
GetAdaptersInfo(NULL,&IfIndex);
SetupInfo.pAdInfo=pTemp=(PIP_ADAPTER_INFO)VirtualAlloc(NULL,IfIndex,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
GetAdaptersInfo(pTemp,&IfIndex);
}catch(Exception &exception)
{
Application->ShowException(&exception);
}
while(pTemp)
{
ComboBox_AddString(hCombo,pTemp->Description);
ComboBox_SetItemData(hCombo,comboindex,pTemp);
pTemp=pTemp->Next;comboindex++;
}return TRUE;
}//------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
if(WSAStartup(MAKEWORD(2,0),&wsadata)!=0)MessageBox(Form1->Handle,"Winsock 初始化出错!","错误",MB_OK|MB_ICONSTOP);
EnumAdapters(Form1->ComboBox1->Handle);
ComboBox_SetCurSel(Form1->ComboBox1->Handle,0);
}
//---------------------------------------------------------------------------void __fastcall TForm1::ToolButton2Click(TObject *Sender) //保存结果
{
HANDLE hFile;
char szPath[MAX_PATH];
AnsiString String;
DWORD nobw;
GetCurrentDirectory(MAX_PATH,szPath);
Form1->SaveDialog1->InitialDir=szPath;
if(!Form1->SaveDialog1->Execute())return;
hFile=CreateFile(SaveDialog1->FileName.c_str(),FILE_ALL_ACCESS,FILE_SHARE_READ,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile==INVALID_HANDLE_VALUE)
{
if(MessageBox(Form1->Handle,"文件已存在,是否要替换?","提示",MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2)==IDYES)
hFile=CreateFile(SaveDialog1->FileName.c_str(),FILE_WRITE_DATA,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
else return;
}//if(hFile==INVALID_HANDLE_VALUE)ShowMessage(IntToStr(GetLastError()));
for(int i=0;i<ListView1->Items->Count;i++)
{
String=String+ListView1->Items->Item[i]->Caption+"\t"+sg(ListView1->Items->Item[i]->SubItems->Text,0);
}
WriteFile(hFile,String.c_str(),String.Length(),&nobw,NULL);
CloseHandle(hFile);
}
//---------------------------------------------------------------------------void __fastcall TForm1::ToolButton1Click(TObject *Sender) //开始扫描
{
DWORD ThreadId;
CloseHandle(CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ScanActiveHost,(LPVOID)NULL,0,&ThreadId));
ToolButton1->Enabled=FALSE;
ToolButton2->Enabled=FALSE;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ComboBox1Change(TObject *Sender)
{
HWND hWndCtrl=Form1->ComboBox1->Handle;
SetupInfo.AdapIndex=((PIP_ADAPTER_INFO)ComboBox_GetItemData(hWndCtrl,ComboBox_GetCurSel(hWndCtrl)))->Index;
//MessageBox(NULL,((PIP_ADAPTER_INFO)ComboBox_GetItemData(hWndCtrl,ComboBox_GetCurSel(hWndCtrl)))->AdapterName,"",1);
}
//---------------------------------------------------------------------------
for (int i=0;i<255;i++)
{
strIp.Format("%d",i+1);
strIp=IpSuffix+strIp;
hthread[i]=CreateThread(NULL,0,ArpThread,strIp.GetBuffer(0),0,NULL);
你不觉得第二次执行strIp=IpSuffix+strIp;会不对??????????????