detecting socket in use on localhost

Discussion in 'Python' started by Berends, Oct 4, 2004.

  1. Berends

    Berends Guest

    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
     
    Berends, Oct 4, 2004
    #1
    1. Advertising

  2. Berends <j@jochem.{N0SP4M}.tv> wrote:

    > 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
     
    Alex Martelli, Oct 4, 2004
    #2
    1. Advertising

  3. Berends

    Berends Guest

    Alex Martelli wrote:
    > Berends <j@jochem.{N0SP4M}.tv> wrote:
    >
    >
    >>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 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.

    >
    >>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:


    > [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
     
    Berends, Oct 4, 2004
    #3
  4. Berends <j@jochem.{N0SP4M}.tv> wrote:
    ...
    > > If you need a cross-platform solution I think you'll need to adopt a
    > > trial-and-error strategy. Two main possibilities:

    ...
    > 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
     
    Alex Martelli, Oct 4, 2004
    #4
  5. Berends

    Berends Guest

    Alex Martelli wrote:
    > 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
    
     
    Berends, Oct 4, 2004
    #5
  6. Berends wrote:
    > 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.
     
    Scott David Daniels, Oct 5, 2004
    #6
  7. Berends

    Bryan Olson Guest

    Berends wrote:

    > Alex Martelli wrote:
    >> Berends wrote:
    >>> 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.


    >> 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.


    "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.


    --
    --Bryan
     
    Bryan Olson, Oct 5, 2004
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Laszlo Nagy
    Replies:
    1
    Views:
    5,017
    Mark Wooding
    Jan 27, 2009
  2. Jean-Paul Calderone
    Replies:
    0
    Views:
    1,014
    Jean-Paul Calderone
    Jan 27, 2009
  3. Laszlo Nagy
    Replies:
    0
    Views:
    584
    Laszlo Nagy
    Feb 1, 2009
  4. Steve Holden
    Replies:
    0
    Views:
    699
    Steve Holden
    Feb 1, 2009
  5. Steve Holden
    Replies:
    1
    Views:
    746
Loading...

Share This Page