Bookstore

Recent

Author Topic: [SOLVED ]Port Checker with Indy 10  (Read 1646 times)

torbente

  • Full Member
  • ***
  • Posts: 229
[SOLVED ]Port Checker with Indy 10
« on: July 21, 2018, 07:56:54 pm »
Testing functionalitys with indy 10, i developed a very small app to detect if the local ports are opened to receive comunications:

EDITED CODE: Now it is working.

Code: Pascal  [Select]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   contador, Start, Finish : Integer;
  4.   IP : String;
  5.   Portsfound : integer = 0;
  6.   MyServer1 : TIdTCPServer;
  7. begin
  8. MyServer1 := TIdTCPServer.Create(form1);
  9. Myserver1.OnExecute:=@form1.IdTCPServer1Execute;
  10. IP := Edit1.Text;
  11.    try
  12.    Start := StrToInt(Edit2.Text);
  13.    Finish := StrToInt(Edit3.Text);
  14.    Except on E:exception do
  15.       Begin
  16.       memo1.lines.Add('Invalid parameters');
  17.       exit;
  18.       end;
  19.    end;
  20. for contador := start to finish do
  21.    begin
  22.    label4.Caption:='Ports found: '+IntToStr(Portsfound);
  23.    application.ProcessMessages;
  24.    MyServer1.Bindings.Clear;  
  25.    MyServer1.DefaultPort:=contador;
  26.       try
  27.       MyServer1.Active:=true;
  28.       memo1.lines.Add('Port available to listent= '+IntToStr(contador));
  29.       Except on E:Exception do
  30.          begin
  31.          memo1.lines.Add('Unable to listen to port= '+IntToStr(contador));
  32.          Continue;
  33.          end;
  34.       end;
  35.    if testcliente(ip,contador) then Portsfound := Portsfound+1;
  36.    MyServer1.Active:=false;
  37.    end;
  38. end;  
  39.  
  40. function TForm1.testcliente(Ip:String;port:Integer):boolean;
  41. var
  42.   mycliente : TIdTCPClient;
  43. begin
  44. result := true;
  45. mycliente := TIdTCPClient.Create(form1);
  46. mycliente.host := ip;
  47. mycliente.Port:=port;
  48. mycliente.ConnectTimeout:=200;
  49. memo1.lines.Add('Connecting to '+Ip+':'+IntToStr(port));
  50.    try
  51.    mycliente.Connect;
  52.    memo1.lines.Add('Connected to port= '+IntToStr(port));
  53.    mycliente.Disconnect;
  54.    except on E:Exception do
  55.       begin
  56.       memo1.lines.Add('Unable to connect to port= '+IntToStr(port)+' '+E.Message);
  57.       result := false
  58.       end;
  59.    end;
  60. mycliente.free;
  61. end;

Example values: IP:= (The user public IP) - Start:= 8005 - Finish := 8010

As a result, the app always can connect ONLY to the first tested port; the server can listen to all ports, but the client is only able to connect to the first one. Seems like something is not freed correctly after first loop, but i can not find what.
Thanks you.
« Last Edit: July 24, 2018, 04:17:32 am by torbente »

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 739
    • Lebeau Software
Re: Port Checker with Indy 10
« Reply #1 on: July 23, 2018, 11:26:12 pm »
As a result, the app always can connect ONLY to the first tested port; the server can listen to all ports, but the client is only able to connect to the first one. Seems like something is not freed correctly after first loop, but i can not find what.

You are not clearing/updating the TIdTCPServer.Bindings collection on each loop iteration.  You are setting only the TIdTCPServer.DefaultPort property, which is used only when adding new binding objects to the collection, but does not update any binding objects that already exist in the collection.  So, you are just re-opening the same listening port on each iteration.

Inside your loop, do this instead:

Code: Pascal  [Select]
  1. for contador := start to finish do
  2. begin
  3.   ...
  4.   if MyServer1.Bindings.Count > 0 then
  5.     MyServer1.Bindings[0].Port := contador
  6.   else
  7.     MyServer1.DefaultPort := contador;
  8.   try
  9.     MyServer1.Active:=true;
  10.     ...
  11.   Except on E:Exception do
  12.   begin
  13.     ...
  14.     Continue;
  15.   end;
  16.   ...
  17. end;
  18.  

Or this:

Code: Pascal  [Select]
  1. for contador := start to finish do
  2. begin
  3.   ...
  4.   MyServer1.Bindings.Clear;
  5.   MyServer1.DefaultPort := contador;
  6.   try
  7.     MyServer1.Active:=true;
  8.     ...
  9.   Except on E:Exception do
  10.   begin
  11.     ...
  12.     Continue;
  13.   end;
  14.   ...
  15. end;
  16.  
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

torbente

  • Full Member
  • ***
  • Posts: 229
Re: Port Checker with Indy 10
« Reply #2 on: July 24, 2018, 04:15:38 am »
Quote
Code: Pascal  [Select]
  1.   MyServer1.Bindings.Clear;

It works. It is necessary any kind of extra specification if i plan re-use an TIdTCPClient ? Or is enough with... ?

Code: Pascal  [Select]
  1. IdTCPClient1.host := ip;
  2. IdTCPClient1.Port:=port;  

... before each use?

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 739
    • Lebeau Software
Re: Port Checker with Indy 10
« Reply #3 on: July 24, 2018, 08:23:25 pm »
It is necessary any kind of extra specification if i plan re-use an TIdTCPClient ? Or is enough with... ?

Code: Pascal  [Select]
  1. IdTCPClient1.host := ip;
  2. IdTCPClient1.Port:=port;  

... before each use?

Depending on HOW you close the client connection, you MIGHT need to clear its InputBuffer before reconnecting, eg:

Code: Pascal  [Select]
  1. if IdTCPClient1.IOHandler <> nil then IdTCPClient1.IOHandler.InputBuffer.Clear;
  2. IdTCPClient1.Connect;
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

torbente

  • Full Member
  • ***
  • Posts: 229
Re: Port Checker with Indy 10
« Reply #4 on: July 26, 2018, 07:26:20 pm »
Depending on HOW you close the client connection, you MIGHT need to clear its InputBuffer before reconnecting, eg:

For safety, i always clear the inputbuffer on disconnections.
Thank you very much.

sadikacar60

  • New Member
  • *
  • Posts: 11
Re: [SOLVED ]Port Checker with Indy 10
« Reply #5 on: February 21, 2020, 01:51:11 pm »
can you share the final version of the code here
thanks