On localhost, how do I pick a free port number?

153,455

Solution 1

Do not bind to a specific port. Instead, bind to port 0:

import socket
sock = socket.socket()
sock.bind(('', 0))
sock.getsockname()[1]

The OS will then pick an available port for you. You can get the port that was chosen using sock.getsockname()[1], and pass it on to the slaves so that they can connect back.

sock is the socket that you created, returned by socket.socket.

Solution 2

For the sake of snippet of what the guys have explained above:

import socket
from contextlib import closing

def find_free_port():
    with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
        s.bind(('', 0))
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        return s.getsockname()[1]

Solution 3

Bind the socket to port 0. A random free port from 1024 to 65535 will be selected. You may retrieve the selected port with getsockname() right after bind().

Solution 4

If you only need to find a free port for later use, here is a snippet similar to a previous answer, but shorter, using socketserver:

import socketserver

with socketserver.TCPServer(("localhost", 0), None) as s:
    free_port = s.server_address[1]

Note that the port is not guaranteed to remain free, so you may need to put this snippet and the code using it in a loop.

Solution 5

You can listen on whatever port you want; generally, user applications should listen to ports 1024 and above (through 65535). The main thing if you have a variable number of listeners is to allocate a range to your app - say 20000-21000, and CATCH EXCEPTIONS. That is how you will know if a port is unusable (used by another process, in other words) on your computer.

However, in your case, you shouldn't have a problem using a single hard-coded port for your listener, as long as you print an error message if the bind fails.

Note also that most of your sockets (for the slaves) do not need to be explicitly bound to specific port numbers - only sockets that wait for incoming connections (like your master here) will need to be made a listener and bound to a port. If a port is not specified for a socket before it is used, the OS will assign a useable port to the socket. When the master wants to respond to a slave that sends it data, the address of the sender is accessible when the listener receives data.

I presume you will be using UDP for this?

Share:
153,455

Related videos on Youtube

Anton L.
Author by

Anton L.

Updated on December 26, 2021

Comments

  • Anton L.
    Anton L. over 2 years

    I'm trying to play with inter-process communication and since I could not figure out how to use named pipes under Windows I thought I'll use network sockets. Everything happens locally. The server is able to launch slaves in a separate process and listens on some port. The slaves do their work and submit the result to the master. How do I figure out which port is available? I assume I cannot listen on port 80 or 21?

    I'm using Python, if that cuts the choices down.

    • David Z
      David Z almost 15 years
      Incidentally, if you just pick a random or random-ish port number (preferably higher than 1024), it'll probably be available. You can even use port 80 or 21 or whatever, as long as no other program is listening on it. At any given time, on a normal system, only a small fraction of ports are in use.
    • Corehpf
      Corehpf almost 15 years
      Picking a random port is not a good idea - let the OS pick one for you.
    • Ciro Santilli OurBigBook.com
      Ciro Santilli OurBigBook.com over 8 years
  • cevaris
    cevaris over 8 years
    See stackoverflow.com/a/2838309/3538289 for an example of sock.bind(('',0))
  • Sebastian
    Sebastian over 8 years
    How do you pass on the number to the slaves? Sounds like a chicken and egg problem to me.
  • mark4o
    mark4o over 8 years
    If the slaves are created after binding, you can just pass it as a parameter when creating them. Alternatively you could write it to some shared memory or a file that both can access, or a central server accessed via some well known port number could keep track of it.
  • codeskyblue
    codeskyblue over 6 years
    if on localhost: maybe s.bind(('localhost', 0)) is better
  • jonEbird
    jonEbird about 6 years
    Also good to add the following so you can quickly re-use that port before your return statement: s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  • Karl Bartel
    Karl Bartel over 4 years
    @jonEbird Does socket.SO_REUSEADDR really help in this case? From what I read, it is only relevant that the socket which is trying to bind has SO_REUSEADDR and it is irrelevant whether that flag is set on the lingering socket.
  • Charlie Parker
    Charlie Parker over 3 years
    what is sock? can you show a full example with an import statement please?
  • user26742873
    user26742873 almost 3 years
    @Sebastian It depends on your case, and is troubling to discuss generally. In my case I just store it in a local text file.
  • hldev
    hldev over 2 years
    @KarlBartel in linux the subprocess will be able to reuse the given addr only if it was bound with SO_REUSEADDR. I tried not using SO_REUSEADDR and the subprocess (google chrome browser) got EADDRINUSE error.
  • Jonathan Liuti
    Jonathan Liuti over 2 years
    This solution is simpler and implies less code but it is also significantly slower than the accepted answer. Accepted answer gives -> 20.2 µs ± 1.5 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each) This solution gives -> 191 µs ± 3.41 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each) ```