detecting socket in use on localhost

B

Berends

I am looking for some code to detect whether or not there is already a
listener to a socket (tcp or udp) on the localhost.

I am writing some software that can be run multiple times on a localhost
and each will instantiate a listener in a range of ports. I have checked
several resources (Cookbook, Python Network Programming (Goerzen),
Programming Python(Lutz)) but cannot find the crux.

Anyone care to point me to some nice methods?

ciao Jochem
 
A

Alex Martelli

Berends said:
I am looking for some code to detect whether or not there is already a
listener to a socket (tcp or udp) on the localhost.

Hmmm, you mean to a _port_, I guess...?
I am writing some software that can be run multiple times on a localhost
and each will instantiate a listener in a range of ports. I have checked
several resources (Cookbook, Python Network Programming (Goerzen),
Programming Python(Lutz)) but cannot find the crux.

Anyone care to point me to some nice methods?

If you need a cross-platform solution I think you'll need to adopt a
trial-and-error strategy. Two main possibilities: try connecting to
that port and see if that succeeds (then there must be some listener) or
fails (then, probably no listener); try binding to that port and see if
that succeeds (then, no listener) or fails because nobody's listening.
In most situations I'd go for the latter, as the former may be less
reliable and might have undesired side effects (at a minimum, footprints
in the listener's logs); however, the latter may not be feasible if the
ports you want to check are privileged ones (<=1024 or whatever) and
your process lacks the necessary privileges.


Alex
 
B

Berends

Alex said:
Hmmm, you mean to a _port_, I guess...?
correct. 1 agent listens on a _single_ port. agents of the same sort can
listen to a single port within a range of ports where similar / other
agents can be active aswell. In my case say 16000-16029.
If you need a cross-platform solution I think you'll need to adopt a
trial-and-error strategy. Two main possibilities:
> [1] try connecting to
that port and see if that succeeds (then there must be some listener) or
fails (then, probably no listener);
[2] try binding to that port and see if
that succeeds (then, no listener) or fails because nobody's listening.
In most situations I'd go for the latter, as the former may be less
reliable and might have undesired side effects (at a minimum, footprints
in the listener's logs); however, the latter may not be feasible if the
ports you want to check are privileged ones (<=1024 or whatever) and
your process lacks the necessary privileges.
Check indeed. These two approaches will be explored, starting with the
try, except pattern. It will be a unprivileged port (16000 up) so
privileges wont be a problem.

I found another solution and that is parse the netstat information on
the host and grep the range of ports and see if something is returned.

In any case thanks for your reply, feedback will be given.

Jochem
 
A

Alex Martelli

Berends said:
...
I found another solution and that is parse the netstat information on
the host and grep the range of ports and see if something is returned.

Oh yes, an unstated corollary of my 'If' above was: if you don't care
about cross-platform portability AND are using a good platform, then
there are no doubt better solutions!


Alex
 
B

Berends

Alex said:
Berends <j@jochem.{N0SP4M}.tv> wrote:
Oh yes, an unstated corollary of my 'If' above was: if you don't care
about cross-platform portability AND are using a good platform, then
there are no doubt better solutions!

_I_ use a good platform, but my boss wants me to make it x-platform ;)

Wrote the code. Seems to be working just fine:

Code:
def determineAvailablePort():
     t = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     t.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

     # Set the first port to bind to, to the minimum port in the range.
     prt = 16000
     isConnected = False
     while not isConnected:
         try:
             t.bind( (myInfo["host"], prt ) )
             isConnected = True
             t.close()
             del t
         except socket.error:
             prt += 1
             if prt > 16029:
                 raise Exception

     return prt
 
S

Scott David Daniels

Berends said:
Wrote the code. Seems to be working just fine:

Code:
def determineAvailablePort():
t = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
t.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# Set the first port to bind to, to the minimum port in the range.
prt = 16000
isConnected = False
while not isConnected:
try:
t.bind( (myInfo["host"], prt ) )
isConnected = True
t.close()
del t
except socket.error:
prt += 1
if prt > 16029:
raise Exception

return prt

You might want to hang on to the port, so that you don't get race
conditions where you determine the port and then some other process
grabs it.

Something like:

def determineAvailablePort(host='localhost'):
skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
skt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# Set the first port to bind to, to the minimum port in the range.
for prt in range(16000, 16030):
try:
t.bind((host, prt))
except socket.error:
pass
else:
return skt, prt
raise Exception, 'No port in 16000:16030 available'

Where the caller uses the opened socket.
 
B

Bryan Olson

Berends said:
>>> I am looking for some code to detect whether or not there is already a
>>> listener to a socket (tcp or udp) on the localhost.
>> Hmmm, you mean to a _port_, I guess...?
>> > correct. [...]
>> [1] try connecting to
>> that port and see if that succeeds (then there must be some listener) or
>> fails (then, probably no listener);
>
>> [2] try binding to that port and see if
>> that succeeds (then, no listener) or fails because nobody's listening.

And Berends had a method [3], which is to ask the system.

A few notes:

Method [1] is one way to do a "port scan". Both network
attackers and defenders regularly do port-scans. Google the
term for further info.

"On the localhost" is open to misinterpretation. The name
'localhost' typically resolves to the loop-back adapter, with
the IPV4 address 127.0.0.1, and is accessible only from the
localhost. Each adapter has its own IP address, with its own
set of TCP ports and UDP ports. Any host with Internet
connectivity should have at least two adapters and addresses:
the loop-back adapter and an external network interface.


Servers most often bind to INADDR_ANY, which is represented by
the reserved (IPV4) address 0.0.0.0, and means the server should
listen on *all* the host's adapters. A request to bind to
(INADDR_ANY, myport) will fail if myport is already bound on any
of the host's adapters.


"Most situations" is hard to define. I know of two common
situations that call for methods like [1]: Server operators
often want to verify their service is running, and often want to
check that common-but-unneeded services are *not* running. The
former calls for a "heartbeat", and the later for a port-scan.
 

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,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top