⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 u_frmsearchnetip.~pas

📁 扫描IP地址和MAC地址、工作组信息软件
💻 ~PAS
📖 第 1 页 / 共 2 页
字号:
{局域网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 + -