you can write a small utility for this purpose in Delphi, using sockects... here's my approach
use this code under you own risk, I present this article for educational purposes only, I take no responsability for the use of it
I'll put a link to the whole demo, here's the unit, I'm sure you can recreate the form and run this:
------- beggining of unit -----
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.
--------- end of unit ---------
as you can see, the idea is pretty easy...
- set the address
- set the port
- try to activate the socket
- and check if it went good
- next port, repeat steps
note:to test ports on your local machine you need to set
IPAddressE.Text:='localhost'
let me know of any bugs
oh, by the way, the source code of the article was formatted using my:
PAS 2 HTML converter
...keep up coding
EberSys