扫描某台电脑的所有开放端口(0-65535),有什么好的办法可以快速完成(1分钟扫描完局域,网的所有电脑的端口)
syn半开放扫描.好像可以,请问怎么实现

解决方案 »

  1.   

    var   
          i:integer;   
          SocketTest:   TServerSocket;   
      begin   
          result:=8800;   
          SocketTest:=TServerSocket.Create(Owner);   
          SocketTest.Active:=true;   
          for   i:=8800   to   9800   do   
          begin   
              socketTest.Close;   
              SocketTest.Port:=i;   
              try   
                  SocketTest.Open;   
                  SocketTest.Close;   
                  SocketTest.Active:=false;   
                  result:=i;   
                  exit;   
              except   
              end;   
          end;
     很久以前的一个东西,这位前辈似乎现在还在csdn工作……
      

  2.   

     Unit   PortScanU;     
        
      Interface     
        
      Uses     
          Windows,   Messages,   SysUtils,   Classes,   Graphics,   Controls,   Forms,     
          Dialogs,   StdCtrls,   ScktComp;     
        
      Type     
          TMainForm   =   Class(TForm)     
              LblIPAddress:   TLabel;     
              IPAddressE:   TEdit;     
              lblScanRange:   TLabel;     
              MinPortE:   TEdit;     
              lblPorttoport:   TLabel;     
              MaxPortE:   TEdit;     
              StatusL:   TLabel;     
              ActivityLB:   TListBox;     
              StartBtn:   TButton;     
              WSsocket:   TClientSocket;     
              StopBtn:   TButton;     
              OpenOnlyCB:   TCheckBox;     
              Procedure   StartBtnClick(Sender:   TObject);     
              Procedure   WSsocketConnect(Sender:   TObject;   Socket:   TCustomWinSocket);     
              Procedure   WSsocketError(Sender:   TObject;   Socket:   TCustomWinSocket;     
                  ErrorEvent:   TErrorEvent;   Var   ErrorCode:   Integer);     
              Procedure   StopBtnClick(Sender:   TObject);     
              Procedure   FormCreate(Sender:   TObject);     
          Private     
              {   Private   declarations   }     
              PortX,   MaxPort:Integer;     
              IsRunning:Boolean;     
              Procedure   SetStuffOnOff(Const   St:Boolean);     
          Public     
              {   Public   declarations   }     
          End;     
        
      Var     
          MainForm:   TMainForm;     
      Implementation     
        
      {$R   *.dfm}     
        
      Procedure   TMainForm.SetStuffOnOff(Const   St:Boolean);     
      Begin     
          IsRunning:=St;     
          StopBtn.Enabled:=St;     
          StartBtn.Enabled:=Not   St;     
          If   Not   (St)   Then     
          Begin     
              ActivityLB.Items.Add('Done   Scanning   '   +   IPAddressE.text);     
              StatusL.Caption:='Status:'     
          End     
      End;     
        
      Procedure   TMainForm.StartBtnClick(Sender:   TObject);     
      Begin     
          ActivityLB.Items.Clear;     
          PortX   :=   StrToInt(MinPortE.text);     
          MaxPort   :=   StrToInt(MaxPortE.text);     
        
          wsSocket.Address   :=   IPAddressE.text;     
          wsSocket.Port   :=   PortX;     
          wsSocket.Active   :=   True;     
        
          SetStuffOnOff(True);     
          ActivityLB.Items.Add('Beginning   scan:   '   +   IPAddressE.text)     
      End;     
        
      Procedure   TMainForm.WSsocketConnect(Sender:   TObject;     
          Socket:   TCustomWinSocket);     
      Begin     
          //socket   connection   made     
          //port   must   be   open!     
          ActivityLB.Items.Add('PORT:   '   +   inttostr(PortX)   +   ';   OPEN!');     
        
          //try   next   port...     
          wsSocket.Active   :=   False;     
          PortX   :=   PortX   +   1;     
          wsSocket.Port   :=   PortX;     
          StatusL.Caption:='Scanning   port:['+IntToStr(PortX)+']';     
        
          If   (IsRunning)   Then     
              If   (PortX   >   MaxPort)   Then     
                  SetStuffOnOff(False)     
              Else     
                  wsSocket.Active   :=   True   //test   the   new   port     
      End;     
        
      Procedure   TMainForm.WSsocketError(Sender:   TObject;   Socket:   TCustomWinSocket;     
          ErrorEvent:   TErrorEvent;   Var   ErrorCode:   Integer);     
      Begin     
          //connection   failed....     
          ErrorCode:=0;   //handle   the   error     
          If   Not   (OpenOnlyCB.Checked)   Then     
              ActivityLB.Items.Add('Port:   '   +   inttostr(PortX)   +   ';   Closed.');     
        
          //try   next   port     
          wsSocket.Active   :=   False;   //close   it     
          PortX   :=   PortX   +   1;               //new   port   to   check     
          wsSocket.Port   :=   PortX;       //put   the   port   in   the   socket     
          StatusL.Caption:='Scanning   port:['+IntToStr(PortX)+']';     
        
          If   (IsRunning)   Then     
              If   (PortX   >   MaxPort)   Then     
                  SetStuffOnOff(False)     
              Else     
                  wsSocket.Active   :=   True   //test   the   new   port     
      End;     
        
      Procedure   TMainForm.StopBtnClick(Sender:   TObject);     
      Begin     
          SetStuffOnOff(False);     
          wssocket.Active   :=   False;     
          ActivityLB.Items.Add('Stoped   scan;   port   '   +   inttostr(PortX)   +   '!')     
      End;     
        
      Procedure   TMainForm.FormCreate(Sender:   TObject);     
      Begin     
          IsRunning   :=   False     
      End;     
        
      End.
    这个全面一些
      

  3.   

    gyk120 的代码调试起来很不方便,能不能把你的窗体代码也贴出来?右击窗体,选择“View as text”可看到窗体代码。
      

  4.   

    问题解决了,用阻塞的办法,设置了超时时间//分端口扫描线程函数
    function ThreadScan(P:pointer):Longint;stdcall;
    var
      PPortPart : PTPortPart;
      i : DWORD;
      ret : Integer;
      strtimeout : String;
      ul : integer;
      fdread : TFDSET;
      timeout : Timeval;
      s : TSocket;
      ServerAddr : TSockAddr;
      TempNode : TTreeNode;
    begin
      PPortPart := PTPortPart(P);
      //扫描端口
      for i:= PPortPart.FirstPort to (PPortPart.FirstPort+PPortPart.PortCount-1) do
      begin
        s := Socket(AF_INET, SOCK_STREAM, 0);
        if (s = INVALID_SOCKET) then       //Socket创建失败
        begin
          showmessage(inttostr(WSAGetLastError())+' Socket创建失败');
          CloseSocket(s);
        end;
        if(setsockopt(s,SOL_SOCKET,SO_SNDTIMEO,@strtimeout,sizeof(strtimeout))=SOCKET_ERROR)
        then begin
          closesocket(s);
          continue;
        end;
        if(setsockopt(s,SOL_SOCKET,SO_RCVTIMEO,@strtimeout,sizeof(strtimeout))=SOCKET_ERROR)
        then begin
          continue;
        end;
        ul := 1;
        ret := ioctlsocket(s, FIONBIO, ul);
        if(ret=SOCKET_ERROR)
        then begin
          closesocket(s);
          continue;
        end;
        ZeroMemory(@ServerAddr,sizeof(ServerAddr));
        ServerAddr.sin_addr.s_addr:=inet_addr(PChar(PPortPart.strIp)) ; //目标IP
        ServerAddr.sin_family := AF_INET;
        ServerAddr.sin_port := htons(i);
        connect(s,ServerAddr,sizeof(ServerAddr)); //连接
        timeout.tv_sec := 0;
        timeout.tv_usec := 2000;
        FD_ZERO(fdread);
        FD_SET(s,fdread);
        ret := select(0, nil, @fdread, nil, @timeout);
        if ( ret <= 0 )
        then begin
          CloseSocket(s);
          continue;
        end;
        CloseSocket(s);
        //将扫描到的开放端口加入TreeView控件TV_PortInfo
        ZeroMemory(@TempNode,sizeof(TempNode));
        TempNode := PortScanFrm.TV_PortInfo.Items.AddChild(PortScanFrm.GetNode,inttostr(i));
        TempNode.ImageIndex := 2;
        TempNode.SelectedIndex := 2;
        {if (Trim(TempNode.Text)=Trim(PortScanFrm.TV_PortInfo.Items.Item[TempNode.Index-1].Text))
        then begin
          PortScanFrm.TV_PortInfo.Items.Item[TempNode.Index-1].Delete;
        end;}
      end;
    end;