📄 u_frmsearchnetip.~pas
字号:
{局域网IP搜索}
unit U_FrmSearchNetIp;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
WinSock,Forms, Dialogs, StdCtrls, ExtCtrls, Buttons,Shellapi,
Grids, ComCtrls;
const
WM_SOCK = WM_USER + 1; {自定义windows消息}
NBTPORT = 137; {向对方的137端口发数据包(UDP包)}
Type
TTGroupNet=record {网络标识}
IP:string;
ComputerName:string;
ComputerDes:string;
NetGroup:string;
NetMacCode:string;
end;
type
TFrmSearchNetIp = class(TForm)
Panel2: TPanel;
Panel1: TPanel;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
EdNetIP1: TEdit;
EdNetIP2: TEdit;
Panel3: TPanel;
Panel4: TPanel;
Panel5: TPanel;
Panel6: TPanel;
SBrnScanNetIP: TSpeedButton;
SBtnStopScan: TSpeedButton;
LabIP: TLabel;
LabStartTime: TLabel;
LabEndTime: TLabel;
LabTime: TLabel;
Label4: TLabel;
PageControl1: TPageControl;
TabSheet1: TTabSheet;
SgDispNetIP: TStringGrid;
BitBtn1: TBitBtn;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure SBtnStopScanClick(Sender: TObject);
procedure SBrnScanNetIPClick(Sender: TObject);
procedure SgDispNetIPSelectCell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);
procedure SgDispNetIPDblClick(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
procedure SgDispNetIPMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
procedure ReadData(var Message: TMessage); message WM_SOCK; {消息接送}
Procedure ClearGrid();
Procedure MakeGrid(Const IntIndex:integer=3);{排序}
public
{ Public declarations }
end;
{*******************************************************}
TComread=class(TThread) {通讯线程}
private
public
Tagg:integer;
protected
procedure Execute; override;
end;
{始化SOCKET}
Procedure WinSockInital(Handle: HWnd);
{关闭SOCKET}
Procedure WinSockClose();
const NbtstatPacket:array[0..49]of byte {发送数据包}
=($0,$0,$0,$0,$0,$1,
$0,$0,$0,$0,$0,$0,$20,$43,$4b,
$41,$41,$41,$41,$41,$41,$41,$41,
$41,$41,$41,$41,$41,$41,$41,$41,
$41,$41,$41,$41,$41,$41,$41,$41,
$41,$41,$41,$41,$41,$41,$0,$0,$21,$0,$1);
{*******************************************************}
var
FrmSearchNetIp: TFrmSearchNetIp;
TF_stop:boolean; {停止}
TempWSAData: TWSAData;
sockfd:TSocket; {Integer socket句柄}
WAIT_ACK_EVENT:Thandle; {LongWord 句柄|}
FSockAddrIn : TSockAddrIn;
IP_count,ComputerIP:integer;
IP_end: Dword;
StartTickCount:DWORD ; {计数器}
StopTickCount: DWORD ;
TGroupNet:array of TTGroupNet;{网络信息寄存}
IntGridCol:integer;
implementation
{$R *.DFM}
procedure TFrmSearchNetIp.FormCreate(Sender: TObject);
begin
IntGridCol:=0;
{Grid清除 ClearGrid}
ClearGrid;
end;
procedure TFrmSearchNetIp.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
TF_stop:=True;
setlength(TGroupNet,0);
{关闭SOCKET}
WinSockClose();
end;
{停止扫描}
procedure TFrmSearchNetIp.SBtnStopScanClick(Sender: TObject);
begin
TF_stop:=True;
end;
{****************** SOCKET通讯 *****************}
{始化SOCKET}
Procedure WinSockInital(Handle: HWnd);
begin
{ 1 初始化SOCKET}
TF_stop:=false;
if WSAStartup(2, TempWSAData)=1 then
begin
showmessage('Socket初始化出错');
exit
end;
{若是用UDP通信,则用}
sockfd:=Socket(AF_INET,SOCK_DGRAM,0);
FSockAddrIn.SIn_Family := AF_INET;
FSockAddrIn.SIn_Port := htons(NBTPORT); {137端口}
{Socket的信息传递--》From.Handle 窗体, FD_READ 在读就绪的时候, WM_SOCK 自定义消息号}
WSAAsyncSelect(sockfd, Handle , WM_SOCK, FD_READ);
{创建事件}
WAIT_ACK_EVENT:=CreateEvent(nil,true,false,pchar('WAIT_ACK') );
ResetEvent(WAIT_ACK_EVENT);
end;
{关闭SOCKET}
Procedure WinSockClose();
begin
TF_stop:=True;
CloseSocket(sockfd); {closesocket函数用来关闭一个描述符为sockfd套接字}
WSACleanup;
sleep(2);
end;
{****************** SOCKET通讯 *****************}
{扫描开始}
procedure TFrmSearchNetIp.SBrnScanNetIPClick(Sender: TObject);
var
DWx1,Dwx:Dword;
IP,Str_Ip:string;
Tcomr:TComread;
begin
Setlength(TGroupNet,0);
{始化SOCKET}
WinSockInital(FrmSearchNetIp.Handle);
{清除Grid}
ClearGrid;
TF_stop:=false;
IP:=trim(EdNetIP1.text);
label4.Caption:='IP个数:';
LabIP.caption:='';
LabStartTime.caption:='开始时间:';
LabEndTime.caption:='结束时间:';
LabTime.caption:='扫描用时:';
if Longword(inet_addr(pchar(IP)))=INADDR_NONE then
begin
Messagebox(Application.handle,pchar(IP + ' TP 出错'),'警告',MB_OK+MB_ICONERROR);
exit;
end;
IP:=trim(EdNetIP2.text);
if Longword(inet_addr(pchar(IP)))=INADDR_NONE then
begin
Messagebox(Application.handle,pchar(IP + ' TP 出错'),'警告',MB_OK+MB_ICONERROR);
exit;
end;
IP:=trim(EdNetIP1.text);
ComputerIP:=inet_addr(PChar(IP)) ; // 192.168.0.1 ===>01 00 A8 C0
str_ip:=inttohex(ComputerIP,8); //01 00 A8 C0
str_ip:=copy(str_ip,7,2)+copy(str_ip,5,2)+copy(str_ip,3,2)+copy(str_ip,1,2); //==> C0 A8 00 01
DWx:=strtoint('$'+str_ip); {转换成为一个长整形数}
str_ip:=inttohex(ComputerIP,8);
str_ip:=inttostr(strtoint('$' + copy(str_ip,7,2)))
+'.' + inttostr(strtoint('$' + copy(str_ip,5,2)))
+'.' + inttostr(strtoint('$' + copy(str_ip,3,2)))
+'.' + inttostr(strtoint('$' + copy(str_ip,1,2)));
EdNetIP1.text:=str_ip; {允许输入 一个数值表示IP}
IP:=trim(EdNetIP2.text);
ComputerIP:=inet_addr(PChar(IP)) ; // 192.168.0.1 ===>01 00 A8 C0
str_ip:=inttohex(ComputerIP,8); //01 00 A8 C0
str_ip:=copy(str_ip,7,2)+copy(str_ip,5,2)+copy(str_ip,3,2)+copy(str_ip,1,2); //==> C0 A8 00 01
DWx1:=strtoint('$'+str_ip); {转换成为一个长整形数}
str_ip:=inttohex(ComputerIP,8);
str_ip:=inttostr(strtoint('$' + copy(str_ip,7,2)))
+'.' + inttostr(strtoint('$' + copy(str_ip,5,2)))
+'.' + inttostr(strtoint('$' + copy(str_ip,3,2)))
+'.' + inttostr(strtoint('$' + copy(str_ip,1,2)));
EdNetIP2.text:=str_ip; {允许输入 一个数值表示IP}
if DWx1>Dwx then
begin
IP_count:=DWx1-Dwx;
ComputerIP:=inet_addr(PChar(trim(EdNetIP1.text)));
IP_end:=DWx1;
label1.caption:='-->>';
end
else begin
IP_count:=DWx-Dwx1;
ComputerIP:=inet_addr(PChar(trim(EdNetIP2.text)));
IP_end:=DWx;
label1.caption:='<<--';
end;
SBrnScanNetIP.Enabled :=false; {屏蔽按键}
Tcomr:=TComread.Create(True);
StartTickCount:=GetTickCount;
LabStartTime.caption:='开始时间:' + FloatToStr(StartTickCount);
Tcomr.Resume ; {开始线程}
end;
{ TComread }
{通讯线程}
procedure TComread.Execute;
var
str_ip:string;
IP_now:Dword;
Procedure MakeEnd();
begin
FrmSearchNetIp.SBrnScanNetIP.Enabled :=True;
StopTickCount:=GetTickCount;
FrmSearchNetIp.LabEndTime.caption:='结束时间:' +FloatToStr(StopTickCount);
FrmSearchNetIp.LabTime.caption:='扫描用时:' +FloatToStr(StopTickCount-startTickCount)+' mS';
FrmSearchNetIp.label4.Caption:='IP个数:'+ inttostr(FrmSearchNetIp.SgDispNetIP.RowCount-1);
FrmSearchNetIp.MakeGrid(3);
{排序
'TP地址'0 '计算机名称'1 '计算机描述' 2
'网络组'3 '网卡MAC码'4
MakeGrid(const IntIndex: integer=3);}
end;
begin
with FrmSearchNetIp do
begin
str_ip:=inttohex(ComputerIP,8); //01 00 A8 C0
str_ip:=copy(str_ip,7,2)+copy(str_ip,5,2)+copy(str_ip,3,2)+copy(str_ip,1,2); //==> C0 A8 00 01
IP_now:=strtoint('$'+str_ip);
while IP_end>=IP_now do ////IP_end==> C0 A8 00 01
begin
if TF_stop=True then
begin
MakeEnd();
{关闭SOCKET}
WinSockClose();
exit;
end;
str_ip:=inttohex(ComputerIP,8);
str_ip:=inttostr(strtoint('$' + copy(str_ip,7,2)))
+'.' + inttostr(strtoint('$' + copy(str_ip,5,2)))
+'.' + inttostr(strtoint('$' + copy(str_ip,3,2)))
+'.' + inttostr(strtoint('$' + copy(str_ip,1,2)));
LabIP.caption:=str_ip; {目前扫描的IP}
FSockAddrIn.SIn_Addr.S_addr := ComputerIP;//inet_addr(pchar(IP));
str_ip:=inttohex(ComputerIP,8); //01 00 A8 C0
str_ip:=copy(str_ip,7,2)+copy(str_ip,5,2)+copy(str_ip,3,2)+copy(str_ip,1,2); //==> C0 A8 00 01
str_ip:=inttohex( strtoint(('$' + str_ip))+1,8); //==> 加一C0 A8 00 02
IP_now:=strtoint('$'+str_ip);
str_ip:=copy(str_ip,7,2)+copy(str_ip,5,2)+copy(str_ip,3,2)+copy(str_ip,1,2); //==>02 00 A8 C0
ComputerIP:=strtoint('$'+str_ip);
sendto(sockfd, NbtstatPacket,50, 0, FSockAddrIn, sizeof(FSockAddrIn));
//发送数据后
ResetEvent(WAIT_ACK_EVENT); // 设为没有信号
end;
MakeEnd();
end;
{关闭SOCKET}
WinSockClose();
end;
{ TFrmSearchNetIp }
{消息接送}
procedure TFrmSearchNetIp.ReadData(var Message: TMessage);
var
Buffer: Array [1..500] of byte;
flen,len,i,j,pos,name_num: integer;
Event: word;
IP:string;
str_tp,str:string;
str_list_IP,str_list_name,str_list_disp,str_list_group,str_list_MAC:string;
StrTp:string;
begin
flen:=sizeof(FSockAddrIn);
Event := WSAGetSelectEvent(Message.LParam);
if Event = FD_READ then
begin
len := recvfrom(sockfd, buffer, sizeof(buffer), 0, FSockAddrIn, flen);
if len> 0 then
begin
//FSockAddrIn.sin_addr.S_un_b.s_b1
with FSockAddrIn.sin_addr.S_un_b do
IP:=format('%d.%d.%d.%d',[ord(s_b1),ord(s_b2),ord(s_b3),ord(s_b4)]);
str_list_IP:=IP;
//数据分析
name_num:=0;
str_tp:='';
for i:=1 to len do
begin
if((buffer[i]=$21)and(buffer[i+1]=$00)and(buffer[i+2]=$01)) then
begin
name_num:=buffer[i+9];
break;
end;
end;
if name_num=0 then exit;
pos:=i+10;
str:='';
for i:=pos to (pos+18*name_num-1) do
begin
if (((i-pos)mod 18) =0) then
begin
for j:=0 to 14 do
begin
if trim(char(buffer[i+j]))='' then buffer[i+j]:=ord(' ');
str:=str+char(buffer[i+j]);
end;
if (buffer[i+16] and $80)=$80 then
begin
if buffer[i+15]=$0 then str_list_GROUP:=trim(str); //网络组
str:=str+format('<%x>',[buffer[i+15]]);
str:=str+'<GROUP>';
end
else begin
if buffer[i+15]=$20 then str_list_name:=trim(str) //计算机名
else
if buffer[i+15]=$3 then str_list_disp:=trim(str);//计算机说明
str:=str+format('<%x>',[buffer[i+15]]);
str:=str+'<UNIQUE>';
end;
str_tp:=str_tp + str +#13+#10;
str:='';
end;
end;
for i:=0 to 5 do
begin
str:=str+format('%.2x.',[buffer[i+pos+18*name_num]]);
end;
delete(str,length(str),1);
str_list_MAC:=trim(str); //网卡的MAC码
str:='MAC: '+str;
str_tp:=str_tp + str + #13+#10;
{网络信息}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -