U_FrmSearchNetIp.pas
资源名称:ScanNetIP.rar [点击查看]
上传用户:hbxylj
上传日期:2013-05-06
资源大小:240k
文件大小:17k
源码类别:
扫描程序
开发平台:
Delphi
- unit U_FrmSearchNetIp;
- interface
- uses
- Windows, Messages, SysUtils, Classes, Graphics, Controls,
- WinSock,Forms, Dialogs, StdCtrls, ExtCtrls, Buttons,
- 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
- TSearchNetIp_frm = class(TForm)
- SBrnScanNetIP: TSpeedButton;
- SBtnStopScan: TSpeedButton;
- stabar: TStatusBar;
- SgDispNetIP: TListView;
- Edit1: TEdit;
- Edit2: TEdit;
- Label1: TLabel;
- Label2: TLabel;
- 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 RxSEdDelayKeyPress(Sender: TObject; var Key: Char);
- 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
- SearchNetIp_frm: TSearchNetIp_frm;
- 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 TSearchNetIp_frm.FormCreate(Sender: TObject);
- begin
- IntGridCol:=0;
- {TRxRichEdit 去除64K的限制}
- //RxRedDispinf.MaxLength := High(Integer) - 1024;
- {Grid清除 ClearGrid}
- ClearGrid;
- end;
- procedure TSearchNetIp_frm.FormClose(Sender: TObject;
- var Action: TCloseAction);
- begin
- TF_stop:=True;
- setlength(TGroupNet,0);
- {关闭SOCKET}
- WinSockClose();
- end;
- {停止扫描}
- procedure TSearchNetIp_frm.SBtnStopScanClick(Sender: TObject);
- begin
- TF_stop:=True;
- close;
- 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 TSearchNetIp_frm.SBrnScanNetIPClick(Sender: TObject);
- var
- DWx1,Dwx:Dword;
- IP,Str_Ip,begin_ip,end_ip:string;
- Tcomr:TComread;
- begin
- //RxRichEdit1.text:='';
- Setlength(TGroupNet,0);
- {始化SOCKET}
- WinSockInital(SearchNetIp_frm.Handle);
- {清除Grid}
- ClearGrid;
- TF_stop:=false;
- begin_ip:=edit1.Text;
- IP:=begin_ip;
- //RxRedDispinf.Text :='';
- stabar.Panels[0].Text:='';
- stabar.Panels[1].Text:='';
- stabar.Panels[1].Text:='扫描用时:';
- if Longword(inet_addr(pchar(IP)))=INADDR_NONE then
- begin
- Messagebox(Application.handle,pchar(IP + ' TP 出错'),'警告',MB_OK+MB_ICONERROR);
- exit;
- end;
- end_ip:=edit2.Text;
- IP:=end_ip;
- if Longword(inet_addr(pchar(IP)))=INADDR_NONE then
- begin
- Messagebox(Application.handle,pchar(IP + ' TP 出错'),'警告',MB_OK+MB_ICONERROR);
- exit;
- end;
- IP:=begin_ip;
- 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:=end_ip;
- 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(begin_ip));
- IP_end:=DWx1;
- end
- else begin
- IP_count:=DWx-Dwx1;
- ComputerIP:=inet_addr(PChar(end_ip));
- IP_end:=DWx;
- end;
- SBrnScanNetIP.Enabled :=false; {屏蔽按键}
- Tcomr:=TComread.Create(True);
- StartTickCount:=GetTickCount;
- Tcomr.Resume ; {开始线程}
- end;
- { TComread }
- {通讯线程}
- procedure TComread.Execute;
- var
- str_ip:string;
- IP_now:Dword;
- Procedure MakeEnd();
- begin
- SearchNetIp_frm.SBrnScanNetIP.Enabled :=True;
- StopTickCount:=GetTickCount;
- SearchNetIp_frm.stabar.Panels[1].Text:='扫描用时:' +FloatToStr(StopTickCount-startTickCount)+' mS';
- SearchNetIp_frm.stabar.Panels[0].Text:='IP个数:'+inttostr(SearchNetIp_frm.SgDispNetIP.Items.Count);
- {排序
- 'TP地址'0 '计算机名称'1 '计算机描述' 2
- '网络组'3 '网卡MAC码'4
- MakeGrid(const IntIndex: integer=3);}
- end;
- begin
- with SearchNetIp_frm 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)));
- stabar.Panels[0].Text:=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));
- //发送数据后
- waitforsingleobject(WAIT_ACK_EVENT,10); // 等待事件变成有信号
- ResetEvent(WAIT_ACK_EVENT); // 设为没有信号
- end;
- MakeEnd();
- end;
- {关闭SOCKET}
- WinSockClose();
- end;
- { TFrmSearchNetIp }
- {消息接送}
- procedure TSearchNetIp_frm.ReadData(var Message: TMessage);
- var
- list:Tlistitem;
- 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;
- {网络信息}
- //RxRedDispinf.Text :=RxRedDispinf.Text +IP + #13+#10+ str_tp+ #13+#10;
- {Grid}
- list:=sgdispnetip.Items.Add;
- list.Caption:=str_list_ip; //'IP地址'
- list.SubItems.Add(str_list_name);//'计算机名称'
- list.SubItems.Add(str_list_GROUP);//'工作组名称'
- list.SubItems.Add(str_list_MAC);//'Mac 地址'
- {
- I:=SgDispNetIP.Items.Count;
- if I=2 then
- begin
- if trim(SgDispNetIP.Items[1].Caption)<>'' then
- begin
- Inc(i);
- SgDispNetIP.RowCount:=I;
- end;
- end
- else begin
- Inc(i);
- SgDispNetIP.RowCount:=I;
- end;
- Dec(i);
- SgDispNetIP.Cells[0,i]:=str_list_IP;//'TP地址'
- SgDispNetIP.Cells[1,i]:=str_list_name;//'计算机名称'
- SgDispNetIP.Cells[2,i]:=str_list_disp;//'计算机描述'
- SgDispNetIP.Cells[3,i]:=str_list_GROUP;//'网络组'
- SgDispNetIP.Cells[4,i]:=str_list_MAC;//'网卡MAC码'
- }
- {
- RichEdit1.Text :=RichEdit1.Text + str_list_IP + ' ' + str_list_name + ' ' +
- str_list_disp + ' ' + str_list_GROUP +' ' + str_list_MAC+ #13+#10
- }
- setlength(TGroupNet,high(TGroupNet)+2);
- TGroupNet[high(TGroupNet)].IP:=str_list_IP;//'TP地址'
- TGroupNet[high(TGroupNet)].ComputerName :=str_list_name;//'计算机名称'
- TGroupNet[high(TGroupNet)].ComputerDes:=str_list_disp;//'计算机描述'
- TGroupNet[high(TGroupNet)].NetGroup:=str_list_GROUP;//'网络组'
- TGroupNet[high(TGroupNet)].NetMacCode :=str_list_MAC;//'网卡MAC码'
- StrTp:=str_list_IP + ' ' +str_list_name+ ' ' +
- str_list_disp + ' ' + str_list_GROUP + ' ' +
- str_list_MAC;
- //RxRichEdit1.Lines.Add(StrTp);
- end;
- SetEvent(WAIT_ACK_EVENT);//有信号
- end;
- end;
- {Grid清除 ClearGrid}
- procedure TSearchNetIp_frm.ClearGrid;
- begin
- SgDispNetIP.Items.Clear;
- end;
- {排序}
- {
- 'TP地址'0
- '计算机名称'1
- '计算机描述' 2
- '网络组'3
- '网卡MAC码'4
- }
- procedure TSearchNetIp_frm.MakeGrid(const IntIndex: integer=3);
- Var
- X,XCount:integer;
- GroupNet:TtGroupNet;
- IntMin:integer;
- list:Tlistitem;
- Procedure GetMinTGroupNet();{获取最小TGroupNet}
- Var
- Y:integer;
- NetMinIP, NetIP:integer;
- DWxMin,DWx:Dword;
- str_ip:string;
- begin
- GroupNet:= tGroupNet[x] ;
- IntMin:=x;
- for Y:=x+1 to XCount do
- begin
- case Intindex of
- 0:begin //'TP地址'0
- NetMinIP:=inet_addr(PChar(GroupNet.IP)) ; // 192.168.0.1 ===>01 00 A8 C0
- str_ip:=inttohex(NetMinIP,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
- DWxMin:=strtoint('$'+str_ip); {转换成为一个长整形数}
- NetIP:=inet_addr(PChar(tGroupNet[y].IP)) ; // 192.168.0.1 ===>01 00 A8 C0
- str_ip:=inttohex(NetIP,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); {转换成为一个长整形数}
- if DWxMin> DWx then
- // if inet_addr(PChar(GroupNet.IP))> inet_addr(PChar(tGroupNet[y].IP)) then
- begin
- IntMin:=y;
- GroupNet:=tGroupNet[IntMin];
- end;
- end;
- 1:begin //'计算机名称'1
- if GroupNet.ComputerName > tGroupNet[y].ComputerName then
- begin
- IntMin:=y;
- GroupNet:=tGroupNet[IntMin];
- end;
- end;
- 2:begin //'计算机描述' 2
- if GroupNet.ComputerDes > tGroupNet[y].ComputerDes then
- begin
- IntMin:=y;
- GroupNet:=tGroupNet[IntMin];
- end;
- end;
- 3:begin //'网络组'3
- if GroupNet.NetGroup > tGroupNet[y].NetGroup then
- begin
- IntMin:=y;
- GroupNet:=tGroupNet[IntMin];
- end;
- end;
- 4:begin //'网卡MAC码'4
- if GroupNet.NetMacCode > tGroupNet[y].NetMacCode then
- begin
- IntMin:=y;
- GroupNet:=tGroupNet[IntMin];
- end;
- end;
- end;{case}
- end;{For}
- end;
- Procedure MakeGrid();{重写Grid}
- Var
- Y:integer;
- StrTp:string;
- begin
- //SgDispNetIP.RowCount:=Xcount+2;
- //RxRichEdit1.Text :='';
- StrTp:='';
- For y:=0 to Xcount do
- begin
- list:=sgdispnetip.Items.Add;
- list.Caption:=TGroupNet[y].IP; //'IP地址'
- list.SubItems.Add(tGroupNet[y].ComputerName);//'计算机名称'
- list.SubItems.Add(tGroupNet[y].NetGroup);//'工作组名称'
- list.SubItems.Add(tGroupNet[y].NetMacCode);//'Mac 地址'
- StrTp:=TGroupNet[y].IP + ' ' +tGroupNet[y].ComputerName+ ' ' +
- tGroupNet[y].ComputerDes + ' ' + tGroupNet[y].NetGroup + ' ' +
- tGroupNet[y].NetMacCode;
- //RxRichEdit1.Lines.Add(StrTp);
- end;{for}
- end;
- begin
- XCount:=high(TGroupNet);
- if XCount<0 then exit;
- {清除Grid}
- ClearGrid;
- for x:=0 to XCount do
- begin
- GetMinTGroupNet();
- if x<>IntMin then
- begin
- GroupNet:=TGroupNet[x];
- TGroupNet[x]:=TGroupNet[IntMin];
- TGroupNet[IntMin]:=GroupNet;
- end;
- end;{for}
- MakeGrid();{重写Grid}
- end;
- procedure TSearchNetIp_frm.SgDispNetIPSelectCell(Sender: TObject; ACol,
- ARow: Integer; var CanSelect: Boolean);
- begin
- IntGridCol:=ACol;
- end;
- procedure TSearchNetIp_frm.SgDispNetIPDblClick(Sender: TObject);
- begin
- MakeGrid(IntGridCol);
- end;
- procedure TSearchNetIp_frm.RxSEdDelayKeyPress(Sender: TObject;
- var Key: Char);
- begin
- if key=#13 then
- SBrnScanNetIPClick(nil);
- end;
- end.