//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
#include "stdio.h"
#include "winsock2.h"
#include "iphlpapi.h"
#pragma comment(lib,"C:\Program Files\Borland\CBuilder6\Lib\Psdk\iphlpapi.lib")
String IPs[255];
String MACs[255];
#define maxThread 60
Mthread *thread[maxThread]; // 线程地址
String GetIP() // 取本地IP
{
WSAData wsaData;
WSAStartup(MAKEWORD(2,0),&wsaData);
char HostName[64];
gethostname(HostName,sizeof(HostName));
HOSTENT *pHost=gethostbyname(HostName);
TStringList *ips=new TStringList;
in_addr **ppAddr=(in_addr **)pHost->h_addr_list;
in_addr *pAddr;
while(pAddr=*(ppAddr++),pAddr!=NULL)
{
String ip=inet_ntoa(*pAddr);
ips->Add(ip);
}
WSACleanup();
ips->QuoteChar=' ';
ips->Delimiter=' ';
String ip=ips->DelimitedText.Trim();
delete ips;
return(ip);
}
String GetMAC(String IP) // 取IP地址对应的MAC地址
{
unsigned char mac[6];
ULONG MacLen=6;
ULONG DestIP=inet_addr(IP.c_str());
int rs=SendARP(DestIP,(ULONG)NULL,(PULONG)mac,(PULONG)&MacLen);
String MACs="";
if (rs==0)
{
char buf[32];
sprintf(buf,"%02X-%02X-%02X-%02X-%02X-%02X",
(unsigned int)mac[0],
(unsigned int)mac[1],
(unsigned int)mac[2],
(unsigned int)mac[3],
(unsigned int)mac[4],
(unsigned int)mac[5]);
MACs=buf;
}
return(MACs);
}
String ip_change(String ip1,int n) // IP址的末址用 n 替換
{
char *ip=ip1.c_str();
unsigned long ipv=inet_addr(ip);
char *add=(char *)&ipv;
add[3]=n;
char * ips=inet_ntoa((struct in_addr &)ipv);
return(String(ips));
}
//-----------------------------------------------------------------
bool stop=false; // 取Mac时中途停止
void __fastcall TForm1::stopBtnClick(TObject *Sender)
{
stop=true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::getBtnClick(TObject *Sender)
{ // 单进程取MAC,慢
unsigned tk0=::GetTickCount();
int ip1=IP1->Text.ToIntDef(1);
int ip2=IP2->Text.ToIntDef(254);
String ip0=IP0->Text;
stop=false;
for (int i=ip1;i<=ip2;i++)
{
String ip=ip_change(ip0,i);
IPL->Caption=ip;
String mac=GetMAC(ip);
if (mac=="")
mac="/";
Memo1->Lines->Add(ip+(char)9+mac);
Application->ProcessMessages();
if (Application->Terminated||stop)
break;
}
StatusBar1->Panels->Items[2]->Text=
::GetTickCount()-tk0;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::GetLocalIPClick(TObject *Sender)
{
String ip0=GetIP();
IP0->Text=ip0;
MAC0->Text=GetMAC(ip0);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
GetLocalIPClick(NULL);
IP1->Text=1;
IP2->Text=254;
//--------------------------------
for (int i=0;i<maxThread;i++)
thread[i]=NULL;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::clearBtnClick(TObject *Sender)
{
Memo1->Lines->Clear(); // 清显示区
}
//---------------------------------------------------------------------------
// 重复利用线程的方法,60个线程可节省5秒
void __fastcall TForm1::AsynGetClick(TObject *Sender)
{ // 多线程取MAC,分段等待,适合时间一致的情况
unsigned tk0=::GetTickCount();
int ip1=IP1->Text.ToIntDef(1);
int ip2=IP2->Text.ToIntDef(254);
String ip0=IP0->Text;
stop=false;
int count;
for (int i=ip1;i<=ip2;i+=count)
{
count=ip2-i+1;
if (count>maxThread)
count=maxThread;
for (int j=0;j<count;j++)
{
if (thread[j]==NULL)
{
thread[j]=new Mthread(true);
thread[j]->FreeOnTerminate=false;
}
int no=i+j;
String ip=ip_change(ip0,no);
IPL->Caption=ip;
IPs[no]=ip;
MACs[no]="";
thread[j]->no=no;
thread[j]->ip=ip;
thread[j]->Resume();
Application->ProcessMessages();
}
bool wait=true;
while (wait) // 待每段线程结束
{
wait=false;
for (int j=0;j<count;j++)
if (!thread[j]->Suspended)
wait=true;
}
for (int j=0;j<count;j++)
{ // 每段结束后,显示
int no=i+j;
Memo1->Lines->Add(IPs[no]+" \x9"+MACs[no]);
Application->ProcessMessages();
}
Application->ProcessMessages();
if (stop || Application->Terminated)
break;
}
StatusBar1->Panels->Items[1]->Text=
::GetTickCount()-tk0;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::QuickBtnClick(TObject *Sender)
{
// 多线程取MAC,最后等待,适合时间不等较重的情况
unsigned tk0=::GetTickCount();
int ip1=IP1->Text.ToIntDef(1);
int ip2=IP2->Text.ToIntDef(254);
String ip0=IP0->Text;
stop=false;
int no=ip1; // no<=ip2
while (no<=ip2)
for (int j=0;j<maxThread;j++)
{
if (thread[j]==NULL) // 寻找结束的线程
{
thread[j]=new Mthread(true);
thread[j]->FreeOnTerminate=false;
}
if (thread[j]->Suspended)
{ // 运行线程
String ip=ip_change(ip0,no);
IPL->Caption=ip;
IPs[no]=ip;
MACs[no]="";
thread[j]->no=no;
thread[j]->ip=ip;
thread[j]->Resume();
no++;
if (no>ip2)
break;
Application->ProcessMessages();
}
}
bool wait=true;
while (wait) // 待线程全部结束
{
wait=false;
for (int j=0;j<maxThread;j++)
if (thread[j]!=NULL)
if (!thread[j]->Suspended)
wait=true;
}
for (int j=ip1;j<=ip2;j++)
{ // 全部结束后,显示
Memo1->Lines->Add(IPs[j]+" \x9"+MACs[j]);
Application->ProcessMessages(