bryan7
asked on
TCP/IP: is port X available ?
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
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
ASKER
that method doesn't work.. as I said above
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)
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)
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.
If it connects you know it is free.
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.
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.
ASKER
Adjusted points from 50 to 100
ASKER
"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..
nothing..
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(d ing.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(d ing.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(d ing.port)+ ' '+'An error occurred when trying to write to the socket connection.');
if ErrorEvent=eeReceive then memo1.lines.add(inttostr(d ing.port)+ ' '+'An error occurred when trying to read from the socket connection.');
if ErrorEvent=eeConnect then memo1.lines.add(inttostr(d ing.port)+ ' '+'A connection request that was already accepted could not be completed.');
if ErrorEvent=eeDisconnect then memo1.lines.add(inttostr(d ing.port)+ ' '+'An error occurred when trying to close a connection.');
if ErrorEvent=eeAccept then memo1.lines.add(inttostr(d ing.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.
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
begin
ding.Active:=false;
ding.Host:=edit3.Text;
ding.Port:=strtoint(edit1.
ding.Active:=true;
end;
procedure TForm1.dingConnect(Sender:
begin
memo1.lines.add(inttostr(d
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(d
if ErrorEvent=eeSend then memo1.lines.add(inttostr(d
if ErrorEvent=eeReceive then memo1.lines.add(inttostr(d
if ErrorEvent=eeConnect then memo1.lines.add(inttostr(d
if ErrorEvent=eeDisconnect then memo1.lines.add(inttostr(d
if ErrorEvent=eeAccept then memo1.lines.add(inttostr(d
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.
so how about it??
Listening...
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:=o verrideExc eption;
End;
Procedure TForm1.overrideException(S ender:TObj ect;E:Exce ption);
Begin
If Pos('10048',E.Message)<>0 Then
Application.MessageBox('Po rt is already in use','MyProgram Error',MB_ICONSTOP Or MB_OK)
Else
Application.MessageBox(PCh ar(E.Messa ge),'MyPro gram 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.
(I have not included the definition, only the declaration)
Procedure TForm1.Form1Create(Sender:
Begin
Application.OnException:=o
End;
Procedure TForm1.overrideException(S
Begin
If Pos('10048',E.Message)<>0 Then
Application.MessageBox('Po
Else
Application.MessageBox(PCh
End;
Procedure TForm1.Button1Click(Sender
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.
ASKER
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
I'll try both things.. about dv I have Delphi 3.0 client/server but I use fpiette's twsocket..
brb.. thanks
Well, that could explain why you don't get the exception. I tested it with the native TCP/IP components of Delphi 4.
ASKER
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 ?
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 ?
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.
ASKER
? 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 ?
ain't there any function or something to check if a port is being used without having to do all this checking stuff ?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
sorry again for my delay.. don't think i forgot about this q. i'll be back later
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
thanx 4 tha comment
ASKER
Adjusted points from 100 to 200
ASKER
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
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
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...
get portx.zip
open the exe on time, and see what happens... then open it for a seccond time...
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(StartA t, 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;
make the clientsocket.onconnect := (procedure) i don't know how. perhaps you can explain this to me.
Function LocateUnusedTCPPort(StartA
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
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;
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;
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
connected := true;
except
Inc(port);
connected := false;
end;
until connected or (port > LASTPORT);
if port > LASTPORT then
Memo1.Lines.Add('No port available');
end;
Awfully quiet out here...
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.
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.
ASKER
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 ?
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 ?
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?
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?
ASKER
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
it listens and once a clienc connects the another socket gets the connection and the server stops
well then if you are using my solution you should disconnect after connect. this only will take a sec and it is 4 initialisation.
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.
:)