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

📄 main.pas

📁 用Delphi编写的一个多线程端口扫描程序代码
💻 PAS
字号:
{
  ------------------------------------------------
     本程序由“啊D”制作!
     QQ:9269563
     E-Mail:paf@163.net
     主页:Http://d99.126.com
     制作于:2002.8.27

  **你可以随意修改代码! 但在转载时请保留此声名!**
  ------------------------------------------------
}
unit main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Buttons, StdCtrls, ComCtrls,winsock,SearchPortThread, Spin;

type
  TForm1 = class(TForm)
    M1: TMemo;
    Port1: TEdit;
    Port2: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Search: TSpeedButton;
    SB1: TStatusBar;
    MaxThread: TSpinEdit;
    Label4: TLabel;
    IP: TComboBox;
    AboutButton: TSpeedButton;
    procedure SearchClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
    procedure AboutButtonClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    procedure Search_ST;
    procedure ThreadDone(Sender: TObject);
    procedure Search_Exit;
    function HostNameToIP(S: string): DWord;
    procedure AddComboBox(CB: TcomboBox);
    procedure SearchOK;
      { Private declarations }
  public
    ThreadList: array of TSearchPortThread;   //线程数组
    Portlist:Tlist; //线程要用到的Strings
    PortIndex:integer; //正在处理的端口号
    MaxPort,MinPort:integer; //保存最大和最小的端口号的变量
    addr:Tsockaddr; //
    About:string; //关于
    StopThread:boolean; //停止线程标记

    { Public declarations }
  end;


  const
  INADDR_NONE = $FFFFFFFF;

var
  Form1: TForm1;

implementation

{$R *.DFM}

{
=============================
=          自定义函数       =
=============================
}

//==== 开始扫描 ====
procedure TForm1.Search_ST();
var
i,j:integer;
Address: DWord;
begin
try
//-- 检测部分 --
Address := HostNameToIP(PChar(IP.text));// 检测IP是否有效!
if (Address = INADDR_NONE) then begin
    showmessage('输入的IP、域名无效或网络不通!');
    exit;
end;

if MaxThread.Value < 2 then begin //检测线程数
    showMessage('线程数请选择 2-300 之间的值!');
    exit;
end;

Maxport:=strtoint(port2.text); //最大端口号
Minport:=strtoint(port1.text); //最小端口号
PortIndex:=Minport;

if Minport > Maxport then begin
    showMessage('[开始端口]不能大于[结束端口]的值!');
    exit;
end;
//端口范围检测
if (minport < 1) or (minport >65535) or (Maxport < 1) or (Maxport >65535) then begin
    showMessage('输入数值超过了指定的范围!'#13#10'数值范围:1-65535');
    exit;
end;
//------扫描部分-------
search.Caption := '停止扫描';
search.tag :=1;
AddComboBox(IP); //把IP或域名加入列表!
m1.lines.Clear;
m1.Lines.Add('正在扫描: ' + ip.text + #13#10'[端口] | [说明]'#13#10'-------------------------------------');
m1.Update;
  SetLength(ThreadList,MaxThread.Value);  //创建 MaxThread.Value 个线程数组
  if (length(threadlist) >1) then j:=length(threadlist)-1;
  if (maxport-minport)<j then j:=maxport-minport;

  for i:=0 to j do
  begin
    addr.sin_family:=AF_INET; //
    addr.sin_addr.S_addr:=Address;  //地址
    addr.sin_port:=htons(PortIndex); //端口

    threadlist[i]:=TSearchPortThread.Create(m1,addr);  //创建线程1
    threadlist[i].OnTerminate :=ThreadDone; //线程处理完后要处理的事
    Portlist.Add(threadlist[i]);  //把线程加入 Portlist
    sb1.Panels[0].Text :=format('已扫描端口: %s',[inttostr(Portindex)]);
    PortIndex:=PortIndex+1;
end;
//出错处理代码
except
showMessage('出错了!');
end;
end;
//===== END =====


//==== 线程退出代码 ======
procedure TForm1.ThreadDone(Sender: TObject);
var
Index:integer;
begin
try

if (PortIndex >= maxport) and (StopThread=false) then begin
    SearchOK();
    StopThread:=true;
    exit;
end;
if (PortIndex > maxport) or (StopThread = true) then exit;

Index := PortList.IndexOf(Sender); //在Filst 中查找刚才的线程对象
PortList.Delete(Index);

addr.sin_port:=htons(portindex); //端口
threadlist[Index]:=TSearchPortThread.Create(m1,addr);  //创建线程1
threadlist[Index].OnTerminate :=ThreadDone; //线程处理完后要处理的事
Portlist.Add(threadlist[Index]);  //把线程加入 Portlist
sb1.Panels[0].Text :='已扫描端口: ' + inttostr(Portindex);
PortIndex:=PortIndex+1;
except //错误处理
//    sb1.Panels[0].Text :='程序出错[线程退出]!';
end;
end;
//===== END =====


//==== 停止扫描 =====
Procedure Tform1.Search_Exit;
var
i:integer;
temp:TSearchPortThread;
begin
try
 m1.Lines.Add('[ 用户中断 ]');
 sb1.Panels[0].Text :='正在关闭线程.....';
for i:=0 to portlist.Count  - 1 do
begin
    temp:=portlist.Items[i];
    temp.Terminate;  //结束线程
end;
      SearchOK(); //显示开始扫描
      StopThread:=true; //StopThread为真,为停止扫描

except //错误处理
//   sb1.Panels[0].Text :='程序出错[停止扫描]!';
end;
end;
//===== END =====

// ===== 扫描完成 =========
procedure Tform1.SearchOK();
begin
      search.Caption :='开始扫描';
      search.Enabled :=true;
      search.tag:=0;
      sb1.Panels[0].Text :='扫描完成';
      m1.Lines.Add('-------------------------------------'#13#10'扫描完成!');
      portlist.Free;//释放PortList的内存空间
end;
//==== END ====

//==== 域名、IP自动转为IP ====
function TForm1.HostNameToIP(S:string):DWord;
var
Host:pHostent;
Address:DWord;
begin
Address := inet_addr(PChar(S));
if (Address = INADDR_NONE) then begin
   Host:=GetHostByName(Pchar(S));
   if Host = nil then begin
        HostNameToIP:=INADDR_NONE;
        exit;
   end
   else begin
        hostNametoip:=longint(pointer(Host^.h_addr_list^)^);
        exit;
   end;
end
else begin
  HostNameToIP:=Address;
  exit;
end;
end;
//==== END ====

//==== 自动把ComboBox控件的内容里没有的内容加入列表中 =====!
procedure Tform1.AddComboBox(CB:TcomboBox);
var
a :integer;
begin
    a:=CB.Items.IndexOf(CB.Text);
    if a=-1 then CB.Items.Add(CB.Text);
end;
//== END ===

// ◎◎◎ 自定义函数 END ◎◎◎




{
=============================
          控件部分
==============================
}

//==== Search按钮 =====
procedure TForm1.SearchClick(Sender: TObject);
begin
if search.tag =0 then begin
    portlist:=Tlist.Create; //创建Tstring
    Search_ST(); //开始
    StopThread:=false; //停止为假时,为扫描
end
else begin
    Search_Exit(); //停止
end;
end;
//===== END =====


//===== Form 创建 =====
procedure TForm1.FormCreate(Sender: TObject);
var
Wsadata:Twsadata;
begin
WSAStartup(Makeword(2,0),Wsadata);//
About:=m1.Text; //把简介内容保存到About变量中
end;
//===== END =====


//===== Form 退出 ======
procedure TForm1.FormDestroy(Sender: TObject);
begin
//PortList.free; //释放PortList的内存空间
WSAcleanUP;//
end;
//===== END ======


//===== 当按‘回车’、‘Esc’键时的动作 ======
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
if (key =#13) and (search.Tag=0) then  SearchClick(Sender); //开始扫描
if (key =#27) and (search.Tag=1) then  SearchClick(Sender); //停止扫描
end;
//===== END ======



//==== 关于 =====
procedure TForm1.AboutButtonClick(Sender: TObject);
begin
showMessage(About +
'地址:深圳市龙岗区坪山镇石井太阳村'#13#10#13#10 +
'注:'#13#10 +
'本软件为免费软件,对使用本软件产生'#13#10 +
'的后果,本人不承担任何的责任!'#13#10#13#10 +
'本程序用Delphi编写,如要源码,请和作者联系!'#13#10#13#10 +
'制作时间: 2002年8月27日'
);
//m1.Text:=About;
end;
//==== END =====

//====== 窗口居中 ======
procedure TForm1.FormShow(Sender: TObject);
begin
     Left := (Screen.Width - Width) div 2;
     Top := (Screen.Height - Height) div 2;
end;
//===== END ====

// ◎◎◎ 控件部分 END ◎◎◎

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -