请问如何快速枚举局域网内所有存活主机IP

badguy2002 2004-07-07 03:19:30
我想快速搜索所有主机,我已经试过以下方法,注意,我强调的是快速
1.用ping,当然可以,但是如果要在程序中实现不大合理,而且我觉得速度也快不到哪里去
2.用winpcap发送arp请求包可以获得,但是获取时间不确定,而且获取速度不算太快
3.用SendARP函数,对于需要扫描255个主机时简直太慢了,不能忍受,感觉程序都无法响应了。于是我尝试着开255个线程分别调用SendARP函数,结果发现大多数SendArp都调用失败,错误值是31。不知道为什么
4.看到网上有人使用先枚举网络资源,再获取主机信息,然后有主机名获取IP,最后由IP获取MAC的方法,我觉得速度也快不到哪里去(这个没有具体试过)
...全文
1651 44 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
44 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhoujiamurong 2004-10-10
  • 打赏
  • 举报
回复
这个铁应该加金
HMLove 2004-07-21
  • 打赏
  • 举报
回复
楼主
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;会不对??????????????
tabris17 2004-07-12
  • 打赏
  • 举报
回复
//---------------------------------------------------------------------------

#include <vcl.h>
#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);
}
//---------------------------------------------------------------------------

wjl_2001 2004-07-10
  • 打赏
  • 举报
回复
楼主:
"关键如果要保证所有回送的arp包能够收到,肯定时间要长一点啊,因为是开线程处理回送的包,只有保证线程有足够的cpu时间,才可能收到所有包。比如,现在机器上现在正在运行一个高优先级,大计算量的线程,那么很可能我的线程得到运行的机会很少,所以只有设置足够长的时间才能保证包都收到并被处理。"
如果你是这么考虑的话,任何扫描都不可能快速的,你说呢?
PiggyXP 2004-07-10
  • 打赏
  • 举报
回复
不行的话,只能想别的办法了.-_-b

其实开 255 的线程实在是多了,因为我以前做扫描器的时候,发现系统开200的线程正好达到系统性能的临界点,多了话反而会造成性能的急剧下降,我的电脑是 P4 2.4 G的

SendARP函数我没有用过,但是我用winpcap做过很多arp包的试验,其实arp包的返回是非常快的,如果觉得不够保险,可以对某主机一次发多个数据包,估计局域网的环境下应该是没有问题的
badguy2002 2004-07-10
  • 打赏
  • 举报
回复
呵呵,今天刚上来就加了啊,呵呵,就是看到大家这么辛苦,这么踊跃啊,呵呵,感谢大家的帮助啊,我结贴了,呵呵!
PiggyXP 2004-07-10
  • 打赏
  • 举报
回复
真加到100分了,什么时候加的我都没注意呵呵
PiggyXP 2004-07-10
  • 打赏
  • 举报
回复
呵呵呵,不错不错,终于能有结果了

收藏一下这个帖子

badguy2002(风一样的男孩)看到大家都这么辛苦的份上,不把帖子加到100分啊^_^
badguy2002 2004-07-10
  • 打赏
  • 举报
回复
呵呵,另外说一下,关于使用WNet函数(WNetEnumResource,WNetEnumResource),我觉得不保险,(效率还行,但是好像枚举的主机不全,不知道为什么)我在以前的帖子中查到
"
列举网络上所有资源

http://www.ittide.com/document/source/netware/network.zip
"
使用它的程序,除了自己工作组内的主机外,还可以列出自己工作组之外的主机,但是还是不全。所以还是建议大家用多线程SendARP方法,速度快,而且枚举的主机全,呵呵,特别推荐!

呵呵,好,问题解决了,如果大家没有什么问题,我就结贴了!
badguy2002 2004-07-10
  • 打赏
  • 举报
回复
呵呵,搞定了,采用多线程调用SendARP的方法不错,效率很高(我的局域网11台机器在线,几秒钟就搞定:))不用每开一个线程就Sleep(),这样速度很慢,可以预先定义一个CString szIp[255];数组,作为255个线程的参数,下面是程序的大概:
//全局变量
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);
}


}
badguy2002 2004-07-10
  • 打赏
  • 举报
回复
to wjl_2001(wjl_2001) ,我举这个例子的意思是说明发送arp包来获取ip/mac对在时间上不确定性,很不好控制,所以为了保证能够收到所有包,只有设置一个较长时间等待
但是其他方法就比较好控制一点,比如说SendARP,可能也会遇到上面的情况,但是它具有确定性,一旦它调用返回的时候,就可以得到mac地址,即使时间再长,但是这个时间是确定的,我是这个意思,就是想知道一个在时间上具有确定性,并且时间相对较短的方法,呵呵
badguy2002 2004-07-10
  • 打赏
  • 举报
回复
to tabris17(四不象) ,哦,明白了,呵呵,Sleep()的作用是让线程能够迅速取得参数,以免参数被后面的线程的参数所改变。呵呵,现在没有错了,谢谢你啊,呵呵

不过,即使开了255个线程,得到所有存活主机的速度还是很慢啊!!你获取的速度怎么样?
badguy2002 2004-07-10
  • 打赏
  • 举报
回复
to tabris17(四不象) ,你说多线程调用SendArp没有问题吗?但是为什么我的有问题,我的代码就贴在上面在,几乎和你的一样
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有区别么??

Hawk_lp 2004-07-10
  • 打赏
  • 举报
回复
呵呵!

收藏之... ...
tabris17 2004-07-10
  • 打赏
  • 举报
回复
啊,忘记说了,上面的代码这里有点问题

WaitForMultipleObjects(255,hthread,TRUE,INFINITE);

WaitForMultipleObjects 函数最多等待 MAXIMUM_WAIT_OBJECTS 个句柄,MAXIMUM_WAIT_OBJECTS 好像是65把,用for语句改进一下就好了

我贴出来的是旧版本的代码,该本版不会判断局域网的子网掩码,星期一贴上新的
PiggyXP 2004-07-10
  • 打赏
  • 举报
回复
TO: tabris17(四不象)

呵呵我不是说SendARP不行,我只是说winpcap发送arp包可以实现

我没有用过SendARP,只是看到楼主说程序无法响应

感谢你带来这么好的东西,如果这样可以的话,就是一个很好的方案了,使用winpcap的

话还要另外装驱动,麻烦
tabris17 2004-07-10
  • 打赏
  • 举报
回复
虽然是C++Builder的源代码,但是是从VC移植来的,VC的代码找不到了



//---------------------------------------------------------------------------

#include <vcl.h>
#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;
}
//---------------------------------------------------------------------------

tabris17 2004-07-10
  • 打赏
  • 举报
回复
to:PiggyXP

就算是开255个线程,其实同时运行的线程也只不过10几个而已,因为如果目标主机存在的话,SendARP函数会很快返回的。


我就写过这么个程序,扫描时对系统性能没什么影响
tabris17 2004-07-10
  • 打赏
  • 举报
回复
SendARP可以的

多线程呀,我写过程序的,没有出错啊,在开启线程之间Sleep以下就好了
DerryZhang 2004-07-09
  • 打赏
  • 举报
回复
Mark
加载更多回复(24)

18,361

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧