check for unused ports and then grab one

B

Brad Tilley

Instead of me arbitrarily assigning a high port number to a variable, is
it possible to check for ports that are unused and then randomly assign
one of them to a variable? Something like this is what I'm thinking:

port = socket.getunusedport()

Any ideas?
 
E

Erik Heneryd

Brad said:
Instead of me arbitrarily assigning a high port number to a variable, is
it possible to check for ports that are unused and then randomly assign
one of them to a variable?

No. Trial and error until you find one.


Erik
 
P

Peter Hansen

Brad said:
Instead of me arbitrarily assigning a high port number to a variable, is
it possible to check for ports that are unused and then randomly assign
one of them to a variable? Something like this is what I'm thinking:

port = socket.getunusedport()

Any ideas?

As Erik says, use a loop until you get a free one, catching the
exceptions that are raised as you try to use the occupied ones.

I'm curious what you are trying to do though. Normally a server
has to listen on a predefined port or the clients won't be able
to connect, and a client doesn't need to specify which port it
will bind to as the OS will pick a free one automatically. I've
never had to do what you are trying to do, thus my curiosity...

-Peter
 
C

Cameron Laird

No. Trial and error until you find one.
.
.
.
Incorrect, if I understand you both; *UNIX Network Programming*
has said for years that
The process can let the system automatically assign
a port. For both the Internet domain and the XNS
domain, specifying a port number of 0 before calling
bind() requests the system to do this.
While I've never tracked down an RFC that specifies this, it surely
exists.
 
J

Josh Close

I believe you should be able to just bind to port 0. Then it will pick
up an available one and you won't have to worry about it.

-Josh
 
M

Michael Fuhr

Erik Heneryd said:
No. Trial and error until you find one.

On many systems, binding to port 0 will give you an available port;
you can then use getsockname() to find out which port you got.

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
sock.bind(('', 0))
sock.listen(socket.SOMAXCONN)
ipaddr, port = sock.getsockname()
print 'listening on %s port %d' % (ipaddr, port)
 
B

Brad Tilley

Cameron said:
.
.
.
Incorrect, if I understand you both; *UNIX Network Programming*
has said for years that
The process can let the system automatically assign
a port. For both the Internet domain and the XNS
domain, specifying a port number of 0 before calling
bind() requests the system to do this.
While I've never tracked down an RFC that specifies this, it surely
exists.

This works... even on winXP... thank you!

import socket

def get_server():
server = socket.gethostbyname(socket.gethostname())
return server

def get_port():
port = 0
return port

def listen(server_param, port_param):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((server_param, port_param))
s.listen(1)
ipaddr, port = s.getsockname()
print ipaddr, port

[/QUOTE]
 
B

Brad Tilley

Peter said:
As Erik says, use a loop until you get a free one, catching the
exceptions that are raised as you try to use the occupied ones.

I'm curious what you are trying to do though. Normally a server
has to listen on a predefined port or the clients won't be able
to connect, and a client doesn't need to specify which port it
will bind to as the OS will pick a free one automatically. I've
never had to do what you are trying to do, thus my curiosity...

-Peter

I use Python for administering windows clients. This software will
facilitate that... that's all.

The server (which resides on the win clients) has to start and configure
itself dynamically. Using the same port number isn't necessary and I
prefer not to hard code it. Each server will have a client component
that grabs the current IP (dhcp) and port number the server is using and
then sends it to a separate machine (sys-admin workstation) that is
collecting a list of ips and ports for later usage.

Brad
 
E

Erik Heneryd

Ah. Nothing you use very often. Closest I've come is opening a
(random) port in some interval.
This works... even on winXP... thank you!

Not very surprising considering that it's network code is based on BSD.


Erik
 
B

Brad Tilley

Erik said:
Ah. Nothing you use very often. Closest I've come is opening a
(random) port in some interval.



Not very surprising considering that it's network code is based on BSD.


Erik

Yeah, if it wasn't for the BSD license, Microsoft and Apple would have
been forced to write more code than they have... there really is a
merciful God ;)
 
B

Brad Tilley

Erik said:
Ah. Nothing you use very often. Closest I've come is opening a
(random) port in some interval.



Not very surprising considering that it's network code is based on BSD.


Erik

Yeah, if it wasn't for the BSD license, Microsoft and Apple would have
been forced to write more code than they have... there really is a
merciful God ;)
 
B

Barry Margolin

[email protected] (Cameron Laird) said:
.
.
.
Incorrect, if I understand you both; *UNIX Network Programming*
has said for years that
The process can let the system automatically assign
a port. For both the Internet domain and the XNS
domain, specifying a port number of 0 before calling
bind() requests the system to do this.
While I've never tracked down an RFC that specifies this, it surely
exists.

There's no reason for it to be in an RFC, because it's an API issue, not
a protocol issue.
 
A

Andrew Dalke

Peter said:
I'm curious what you are trying to do though. Normally a server
has to listen on a predefined port or the clients won't be able
to connect, and a client doesn't need to specify which port it
will bind to as the OS will pick a free one automatically. I've
never had to do what you are trying to do, thus my curiosity...

I needed something like this once. I wanted to write
an interface to an external program. It didn't take
stdin/stdout/files for input. Instead, it acted as a
server and I needed to make a network connection to it.

It took a port number on the command line so I first
scanned a range to ensure a port was available then
passed that port number to the exec'd client.

Yes, there's a race condition, but at most I expected
two or three processes running on the system, all
from friendly users. AFAICT there never was a problem.

Since then the vendor changed the code to support
connections via stdin/stdout.

Andrew
(e-mail address removed)
P.S.
And the port 0 trick is new to me too.
 
P

Peter Hansen

Brad said:
I use Python for administering windows clients. This software will
facilitate that... that's all.

The server (which resides on the win clients) has to start and configure
itself dynamically. Using the same port number isn't necessary and I
prefer not to hard code it. Each server will have a client component
that grabs the current IP (dhcp) and port number the server is using and
then sends it to a separate machine (sys-admin workstation) that is
collecting a list of ips and ports for later usage.

Thanks for the explanation Brad. Interesting usage. I suspect
in the same situation I'd make the choice to assign a port to
the service permanently (and hardcode or whatever), but I have
to admit I don't have all the details so maybe I'd take your
approach, too. :)

-Peter
 
M

Michael Sparks

Peter Hansen wrote:
....
I'm curious what you are trying to do though. Normally a server
has to listen on a predefined port or the clients won't be able
to connect, and a client doesn't need to specify which port it
will bind to as the OS will pick a free one automatically. I've
never had to do what you are trying to do, thus my curiosity...

One place where it is useful in an non-passive FTP client. IE It needs
to allow the server to connect back to an port on the client for
transfer of data. The client tells the server the IP/port number, and
since the client doesn't normally have one of these open it's often
useful just to let the local TCP stack allocate the port number, find
out what it is and tell the server.

Regards,


Michael.
--
(e-mail address removed)
British Broadcasting Corporation, Research and Development
Kingswood Warren, Surrey KT20 6NP

This message (and any attachments) may contain personal views
which are not the views of the BBC unless specifically stated.
 
B

Brad Tilley

Brad said:
This works... even on winXP... thank you!

import socket

def get_server():
server = socket.gethostbyname(socket.gethostname())
return server

def get_port():
port = 0
return port

def listen(server_param, port_param):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((server_param, port_param))
s.listen(1)
ipaddr, port = s.getsockname()
print ipaddr, port

Not that it matters, but this code always gets a much higher port number
on my Linux computers:

IDLE 1.0.4
 
M

Michael Fuhr

Brad Tilley said:
def listen(server_param, port_param):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((server_param, port_param))
s.listen(1)
ipaddr, port = s.getsockname()
print ipaddr, port
[snip]

Not that it matters, but this code always gets a much higher port number
on my Linux computers:

Different systems have different ephemeral port ranges; they can
often be configured. Here are some examples:

Linux
$ sysctl net.ipv4.ip_local_port_range
net.ipv4.ip_local_port_range = 32768 61000

FreeBSD
$ sysctl net.inet.ip.portrange
net.inet.ip.portrange.lowfirst: 1023
net.inet.ip.portrange.lowlast: 600
net.inet.ip.portrange.first: 1024
net.inet.ip.portrange.last: 5000
net.inet.ip.portrange.hifirst: 49152
net.inet.ip.portrange.hilast: 65535
net.inet.ip.portrange.randomized: 1

Solaris
$ ndd /dev/tcp tcp_smallest_anon_port
32768
$ ndd /dev/tcp tcp_largest_anon_port
65535
 
A

Alex Martelli

Peter Hansen said:
...
in the same situation I'd make the choice to assign a port to
the service permanently (and hardcode or whatever), but I have
to admit I don't have all the details so maybe I'd take your
approach, too. :)

One key detail we have is that the current IP cannot be known in
advance, thanks to DHCP -- it has to be communicated dynamically to a
sys-admin workstation. Given that key detail, I see no problem having
to communicate the port number as well as the IP address, thus no
advantage in hardwiring the port number -- as long as no firewalls and
similar hacks are in the way, of course.

One alternate approach might be to support zeroconf/rendezvous/
opentalk/or however it's called today. Basically, it's a clever hack on
top of DNS, recently blessed by the IETF (not sure about the RFC number,
but no doubt they did assign one to it when they blessed it), that makes
it a cakewalk for servers and clients for any given protocol to find
each other, just as long as they know the name of the protocol. Well
supported for Python as well as any other language you may care about (a
Ruby interface was put together by two people hacking on their laptops
in the half-day of time zeroconf's inventor and chief prophet, Stuart
Cheshire, was tutorialing about it at OSCON...), native on Macs, a
simple add-on for Windows and Linux, lightweight, potentially tiny (a
suitably slimmed-down minimal implementation was fitted into ROM on the
8-bit embedded processor-cum-ROM of some standalone net-connected webcam
in just a few Kb...!)... a true delight, all it needs is for more apps
to support it (and I like it a lot, which is why I miss no occasion to
offer a plug fot it;-).


Alex
 
P

Peter Hansen

Alex said:
One key detail we have is that the current IP cannot be known in
advance, thanks to DHCP -- it has to be communicated dynamically to a
sys-admin workstation. Given that key detail, I see no problem having
to communicate the port number as well as the IP address, thus no
advantage in hardwiring the port number -- as long as no firewalls and
similar hacks are in the way, of course.

There's at least one advantage I can think of offhand, which is
that by assigning a port number in advance, I make troubleshooting
much easier... even possible! Having each instance of the
server grab a possibly different port number would be a
major hassle when it came to things like trying to run
tcpdump or Ethereal or some other protocol analyzer, especially
if one wasn't on either the client or the server machine.

But I take your point. Hardcoding the one thing when the
other cannot be provides less advantage than it normally
would.

-Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top