Solved

TCP/IP: is port X available ?

Posted on 2000-04-21
31
603 Views
Last Modified: 2010-04-04
how do I know if a certain tcp/ip port is available ?

this doesn't work:

with wsocket1 do
 begin
  port:= '20000';
  proto:= 'tcp';
  try
    listen;
  except
    showmessage('port not available');
  end;
 end;

this only works when another app is LISTENNING in that port..
I tried the following:

I run a chat program that conects to another one in LOCALHOST,
both in my computer, ok I go to netstat and I see there are these
connections:

localhost:20000 --> localhost:30000
localhost:30000 --> localhost:20000

ok, once they are connected and not listenning.. just connected, I try the code above and I get these results:
if I try with port 20000 I get an error about winsock binding or something,
if I try with 30000 .. I get no error !!! like if the port was free while it's not...

thanks

 
0
Comment
Question by:bryan7
  • 12
  • 10
  • 3
  • +4
31 Comments
 
LVL 1

Expert Comment

by:tomer_engel
ID: 2740197
a) every applciation determins it's own ports,,meaning , if you're writng serverand the client applciations you should write down in the Sockets propery the port.
b) if your'e writing only the server then run in a for loop until you find a port that isn't unsed(something like that):

for i:=1000 to 5000 do
begin
  try
    port := i;
    //connect
    break;//break out of the loop
  except
  end;//the try-except
end;//the for loop

otherwise i'm not fammiliar with a function/method/API function that do the check for ya.


:)
0
 
LVL 3

Author Comment

by:bryan7
ID: 2740772
that method doesn't work.. as I said above
0
 
LVL 1

Expert Comment

by:nrico
ID: 2740959
So maybe the Try...Except doesn't work, but I'm sure you'll get an error from the TServerSocket if you're trying to listen on a port that's already occupied.
So instead of using the Try...Except, try hooking the OnError event of the TServerSocket and the OnException event of the TApplication variable, and see what those come up with if you try to listen on a port that you KNOW is occupied.

(I'm guessing for the OnException, personally)
0
 
LVL 1

Expert Comment

by:jturpin
ID: 2744708
You could include a TClientSocket on the server side, then simply change the port to the one you want to connect to.

If it connects you know it is free.
0
 
LVL 4

Expert Comment

by:Radler
ID: 2745648
There are two worlds, Unix and M$.
To Unix machines following the RFC number ??? to detect the port/protocol/service name you should read the lmhost file, but is it true for M$ Windows ?

T++, Radler.
0
 
LVL 3

Author Comment

by:bryan7
ID: 2758068
Adjusted points from 50 to 100
0
 
LVL 3

Author Comment

by:bryan7
ID: 2758069
"So maybe the Try...Except doesn't work, but I'm sure you'll get an error from the                   TServerSocket if you're trying to listen on a port that's already occupied. "

nothing..
0
 
LVL 7

Expert Comment

by:God_Ares
ID: 2764379
don't use a server socket  use a client socket.. if it connects the port is being used.. simple...
soure:...

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ScktComp, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Edit3: TEdit;
    Label3: TLabel;
    Button1: TButton;
    Memo1: TMemo;
    Label4: TLabel;
    ding: TClientSocket;
    poin: TTimer;
    procedure Button1Click(Sender: TObject);
    procedure dingConnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure dingError(Sender: TObject; Socket: TCustomWinSocket;
      ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    procedure poinTimer(Sender: TObject);
    procedure dingRead(Sender: TObject; Socket: TCustomWinSocket);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
  ding.Active:=false;
  ding.Host:=edit3.Text;
  ding.Port:=strtoint(edit1.text);

  ding.Active:=true;

end;

procedure TForm1.dingConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
  memo1.lines.add(inttostr(ding.port)+'  is listening');
  poin.Enabled:=true;
end;

procedure TForm1.dingError(Sender: TObject; Socket: TCustomWinSocket;
  ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
  errorcode:=0;
  if ErrorEvent=eeGeneral then memo1.lines.add(inttostr(ding.port)+'  '+'The socket received an error message that does not fit into any of the following categories.');
  if ErrorEvent=eeSend then memo1.lines.add(inttostr(ding.port)+'  '+'An error occurred when trying to write to the socket connection.');
  if ErrorEvent=eeReceive then memo1.lines.add(inttostr(ding.port)+'  '+'An error occurred when trying to read from the socket connection.');
  if ErrorEvent=eeConnect then memo1.lines.add(inttostr(ding.port)+'  '+'A connection request that was already accepted could not be completed.');
  if ErrorEvent=eeDisconnect then memo1.lines.add(inttostr(ding.port)+'  '+'An error occurred when trying to close a connection.');
  if ErrorEvent=eeAccept then memo1.lines.add(inttostr(ding.port)+'  '+'A problem occurred when trying to accept a client connection request.');
  poin.Enabled:=true;
end;

procedure TForm1.poinTimer(Sender: TObject);
var a,b:integer;
begin
  ding.Active:=false;
  a:=ding.port;
  if a<strtoint(edit2.text) then inc(a);
  ding.port:=a;
  b:=strtoint(edit2.text)+1;
  if a>=b then ding.Active:=true;

  poin.Enabled:=false;
end;

procedure TForm1.dingRead(Sender: TObject; Socket: TCustomWinSocket);
var a:string;
begin
  a:=socket.ReceiveText;
  memo1.lines.add('text'+a);
end;

end.
0
 
LVL 7

Expert Comment

by:God_Ares
ID: 2772983
so how about it??
0
 
LVL 4

Expert Comment

by:Radler
ID: 2773310
Listening...
0
 
LVL 1

Expert Comment

by:nrico
ID: 2793845
I don't know what Delphi version you are using, but this works just fine for me:
(I have not included the definition, only the declaration)

Procedure TForm1.Form1Create(Sender:TObject);
Begin
  Application.OnException:=overrideException;
End;

Procedure TForm1.overrideException(Sender:TObject;E:Exception);
Begin
  If Pos('10048',E.Message)<>0 Then
    Application.MessageBox('Port is already in use','MyProgram Error',MB_ICONSTOP Or MB_OK)
  Else
    Application.MessageBox(PChar(E.Message),'MyProgram Error',MB_ICONSTOP Or MB_OK);
End;

Procedure TForm1.Button1Click(Sender:TObject);
Begin
  ServerSocket1.Port:=5000; // Or whatever you wish
  ServerSocket1.Listen;
End;

This piece of code will give you an error if port 5000 is already in use, and else it'll listen on port 5000.
With my Delphi 4, this works perfectly!

P.S: The 10048 is just the errorcode you'll get from the TServerSocket. I check if it's in the message; if so, the port is occupied.
0
 
LVL 3

Author Comment

by:bryan7
ID: 2794366
sorry for the long delay.. I'm still testing..
I'll try both things.. about dv I have Delphi 3.0 client/server but I use fpiette's twsocket..

brb.. thanks
0
 
LVL 1

Expert Comment

by:nrico
ID: 2799328
Well, that could explain why you don't get the exception. I tested it with the native TCP/IP components of Delphi 4.
0
 
LVL 3

Author Comment

by:bryan7
ID: 2800313
k, this happened:

god_ares solution:
it worked.. giving different error numbers depending if port was listenning or already connected.. but I can't use that because it could leave in an inoperable state the app that is listenning.. let's suppose a program is listenning for the client on port 20000, once the client connects and disconnects the app will not listen again, ok using the proposed solution would could
leave the app not listenning.. I need something that doesn't interfere in any app that's listenning..

nrico's solution:

my app uses twsocket listenning on port x, using addr= 0.0.0.0
when I try tserversocket to listen I don't get any error.. it seems to be listenning..
then I try to connect the client.. and it connects to the demo with tserversocket in stead of my app with twsocket..

in stead.. if I use 'localhost' in stead of '0.0.0.0' for twsocket to listen, the demo with serversocket gives an error..    what's happening ?

0
 
LVL 7

Expert Comment

by:God_Ares
ID: 2804141
that's should not be possible. The program uses the 3 way handshake.. if it does'nt do this then, and only than could a port quit listening.
0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 3

Author Comment

by:bryan7
ID: 2805246
? I don't understand your last comment..


ain't there any function or something to check if a port is being used without having to do all this checking stuff ?
0
 
LVL 7

Accepted Solution

by:
God_Ares earned 200 total points
ID: 2938624
>god_ares solution:
it worked.. giving different error numbers depending if port was listenning or already connected.. but I can't use that because it could leave in an inoperable state the app that is listenning..

a server socket can handle more than 1 connection...

let's suppose a program is listenning for the client on port 20000, once the client connects and disconnects the app will not listen again, ok using the proposed solution would could
leave the app not listenning.. I need something that doesn't interfere in any app that's listenning..



My solution can't interfere or leave the app in a inoperate state.. if you want to check if a port is being used just check on 127.0.0.1 if port x is listening by connectiong to it whit a client socket, that's all and it won't do any harm.

PROOF ME THAT I'M WRONG! and i'll find another way..
0
 
LVL 3

Author Comment

by:bryan7
ID: 3270015
sorry again for my delay.. don't think i forgot about this q. i'll be back later
0
 
LVL 7

Expert Comment

by:God_Ares
ID: 3273610
k cool... i have checked with a programmer from cute ftp server and they are doing it like me.. i'll write some aditional code 4 u... (couze i'm bored :-}  )

thanx 4 tha comment
0
 
LVL 3

Author Comment

by:bryan7
ID: 3290772
Adjusted points from 100 to 200
0
 
LVL 3

Author Comment

by:bryan7
ID: 3290773
umm some code.. great !
umm i was so busy lately i was working to get some money and didn't make much programming.

i double the points for the long delay.. I'll try the code now
0
 
LVL 7

Expert Comment

by:God_Ares
ID: 3329493
http://www.angelfire.com/ok/GODARES/downl.html

get portx.zip

open the exe on time, and see what happens... then open it for a seccond time...
0
 
LVL 7

Expert Comment

by:God_Ares
ID: 3366874
you should make somting like this

make the clientsocket.onconnect := (procedure)  i don't know how.  perhaps you can explain this to me.

Function LocateUnusedTCPPort(StartAt, EndAt : Integer) : Integer;

var
  ClientSocket : TClientSocket;
  free : integer;

procedure ClientSocketError(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
  errorcode:=0;
  free := 1;
end;

procedure ClientSocketConnect(Sender: TObject;
  Socket: TCustomWinSocket); TSocketNotifyEvent;
begin
  free:=0;
end;


begin
  ClientSocket := TClientSocket.Create(Nil);
  free:=-1;
  try
    ClientSocket.Address := '127.0.0.1'; {SKIP}
    ClientSocket.Host := '127.0.0.1'; {SKIP}
    ClientSocket.Port := StartAt - 1;

//    Clientsocket.OnConnet
    ClientSocket.OnConnect := ClientSocketConnect;

    Repeat
      ClientSocket.Port := ClientSocket.Port + 1;
      Result := ClientSocket.Port;
      ClientSocket.active:=true;
      repeat until (free<>-1)
    Until (free=1) or (ClientSocket.Port = EndAt);

  finally
    ClientSocket.Free;
  end;
end;
0
 
LVL 13

Expert Comment

by:Epsylon
ID: 3522762
I've created a demo project that lists all used ports:

http://eps.yi.org/download.asp?file=WSPorts.zip

I got the idea from the TCPSTAT program from Crits Vadim, which is included in the zip file.


However I still prefer to use some code like this to find an unused port:

procedure TForm1.FormCreate(Sender: TObject);
const
  FIRSTPORT = 6000;
  LASTPORT  = 6999;
var
  port: Integer;
  connected: Boolean;
begin
  Memo1.Clear;
  port := FIRSTPORT;
  repeat
    try
      ServerSocket1.Port := port;
      ServerSocket1.Active := true;
      Memo1.Lines.Add('Listening on port ' + IntToStr(port));
      connected := true;
    except
      Inc(port);
      connected := false;
    end;
  until connected or (port > LASTPORT);
  if port > LASTPORT then
    Memo1.Lines.Add('No port available');
end;
0
 
LVL 13

Expert Comment

by:Epsylon
ID: 3605032
Awfully quiet out here...
0
 
LVL 7

Expert Comment

by:God_Ares
ID: 3675139
This question has been up since
4/22/00,

so Bryan7, when are you going to grade this question?

your question has been answerd by me and by Epsylon... both of us gave you good sample code.

0
 
LVL 3

Author Comment

by:bryan7
ID: 3702534
0
 
LVL 3

Author Comment

by:bryan7
ID: 3951873
well finally I'm active again into delphi.

I tried God_ares solutions again and they always give me some winsock error. it only works if there's a socketserver LISTENNING. but what happens if...

app A is listenning on port 6000
app B connects to it on port 6000

now app A associates this connection to a client so app A is not listenning anymore.
now there is a stablished connection between these 2 apps.

TCP    127.0.0.1:1026         127.0.0.1:6000        ESTABLISHED

TCP    127.0.0.1:6000        127.0.0.1:1026         ESTABLISHED


at this point God_Ares solution didn't work.

I tried your code Epsylon, and also didn't work.. but... WSPorts works great ! it lists all the ports being used at the point said before..

I will give this 200 points with A grade to god_ares for all the tries and time spent with me..  a million thanks, and sorry sorry sorry for not being able to test this before.


about Epsylon.. i will give you another 200p.
can i use your code (wsports) in my apps ?
and if they get commercial ?
0
 
LVL 7

Expert Comment

by:God_Ares
ID: 3962892
duh.. your server socket can cope with more than 1 connection. If you wrote a webserver your serversocket would listen on port 80 right?.. and if you would check with netstat is a connection was made you would see

x.x.x.x   listening

and when 1 client would connect you would see

x.x.x.x   ESTABLISHED

but don't you think you would make your serversocket can handle more than 1 connection??? if that wasn't possible how do sites like microsoft.com handle all it's connections?

understand?
0
 
LVL 3

Author Comment

by:bryan7
ID: 3962933
uh i don't want my server to have more than 1 conn..
it listens and once a clienc connects the another socket gets the connection and the server stops
0
 
LVL 7

Expert Comment

by:God_Ares
ID: 3963410
well then if you are using my solution you should disconnect after connect. this only will take a sec and it is 4 initialisation.
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
This video discusses moving either the default database or any database to a new volume.
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now