delphi端口扫描源程序

{
  ------------------------------------------------
     本程序由“啊D”制作!
     QQ:9269563
     E-Mail:paf@163.net
     主页:Http://coold.cn99.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;

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;
const
  INADDR_NONE = $FFFFFFFF;
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.

 

 

 


____________________________________________________________________________________________

 

果你写扫描程序可千万不要直接去连接,应该使用别的链接方法,否则你的踪迹会被别人
发现.例如使用sys扫描或者fin扫描:
我给你异步socket的api代码:
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls,WInSock, ExtCtrls;

const WM_SOCKET=WM_USER+1;   //socket消息

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Panel1: TPanel;
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    Sockhd : integer;   //socket句柄
    Serv_Addr : Tsockaddr;//目标地址

  procedure SockEvent(var msg: Tmessage);message WM_SOCKET;   //处理cocket消息
  procedure DspMsg(msg : string);   //显示信息
    { Private declarations }
  public
    { Public declarations }
  end;

  Form1: TForm1;

implementation
{$R *.DFM}

function lookup_hostname(const hostname:string):longint;  //把域名转化成IP地址
var
  RemoteHost : PHostEnt;  (* no, don't free it! *)
  ip_address: longint;
begin
  ip_address:=-1;
  try
    if hostname='' then
      begin  (* no host given! *)
        lookup_hostname:=ip_address;
        EXIT;
       end
    else
      begin
        ip_address:=Winsock.Inet_Addr(PChar(hostname));  (* try a xxx.xxx.xxx.xx first *)
        if ip_address=SOCKET_ERROR then begin
        RemoteHost:=Winsock.GetHostByName(PChar(hostname));
        if (RemoteHost=NIL) or (RemoteHost^.h_length<=0) then
          begin
            lookup_hostname:=ip_address;
            EXIT;  (* host not found *)
          end
        else
          ip_address:=longint(pointer(RemoteHost^.h_addr_list^)^);
      end;
      end;
   except
    ip_address:=-1;
  end;
  lookup_hostname:=ip_address;
end;

procedure TFOrm1.DspMsg(msg: string);
begin
 memo1.Lines.Add(msg+'...');
 if Memo1.Lines.Count>200 then Memo1.Lines.Delete(0);
end;

procedure TForm1.SockEvent(var msg : tmessage);  //处理socket消息
begin
 case msg.LParam of
  FD_READ: begin    //标识可以读数据,当然肯定已经链接上了
    dspmsg('可以读取数据');
    //do what you want do
  end;

  FD_WRITE: begin
    dspmsg('可以发送数据');
    //do what you want do
  end;

  FD_ERROR: begin
    dspmsg('发生错误');
     //如果你是客户端,则应该是连接不上,即端口没有开
  end;

  FD_CLOSE: Begin
    dspmsg('服务器断开连接');
    //对方关闭连接
  end;

  FD_CONNECT: begin
    dspmsg('连结上服务器');
    //表示对方端口开放
  end;

  FD_ACCEPT: begin
    dspmsg('接收一个请求');
   //这个消息只有服务端可能出现
  end;
 end;
end;

procedure TForm1.FormCreate(Sender: TObject);
 var  wsaData:TwsaData;
begin                 //启动winsock动态链接库
  if WSAStartup (makeword(2,2), wsaData)<>0 then begin
    messagebox(application.handle,'无法启动winsock动态连接库!','警告',MB_OK or MB_APPLMODAL or MB_ICONWARNING);
    Application.Terminate;
  end; 
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin    //关闭dll
 WSACleanup;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 Sockhd := socket(AF_INET,SOCK_STREAM,0);  //创建socket句柄
 if Sockhd<0 then begin
   messagebox(application.handle,'无法创建句柄!','警告',MB_OK or MB_APPLMODAL or MB_ICONWARNING);
   exit;
 end;
  Serv_addr.sin_addr.s_addr:= lookup_hostname(edit1.Text);  //主机名
  Serv_addr.sin_family := PF_INET;
  Serv_addr.sin_port := htons(23);      //any port you want to connect

  if WSAAsyncSelect(Sockhd,Form1.handle,WM_SOCKET,FD_ACCEPT or FD_CONNECT or FD_CLOSE or  FD_READ or FD_WRITE)=SOCKET_ERROR
  then begin
   messagebox(application.handle,'无法创建句柄!','警告',MB_OK or MB_APPLMODAL or MB_ICONWARNING);
   exit;
  end;   //异步socket
  connect(sockhd,serv_addr,sizeof(serv_addr));  //连接,结果会在前面的处理函数处理
end;

end.
相信应该可以满足你的要求
 
 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值