Search code examples
pythonsocketsnetwork-programmingmultiprocessingthreadpool

Best way to find which port is selected from client-side


My program randomly selects a port server-side using address ('0.0.0.0', 0) and a unique code is sent to the client-side where the socket is trying to connect to every port within a range and checking for the same code to confirm the correct server port.

The problem is iterating through all the ports (range(1024, 65336)), and trying to connect to each one of them is very slow even if ThreadPool is used.


This is just an example to show what I'm trying to do. My main program host over the internet not on localhost.

server.py

import socket 

CODE = 'Code123' # just an example

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
addr = ('0.0.0.0', 0)
server.bind(addr)

# Can see which port is assigned
print(server)

def start():
    server.listen(5) # connect to 5 connection.
    while True:
        conn, addr = server.accept()
        conn.send(CODE.encode('utf-8'))
        print("Code Sent")

start()

cilent.py

import socket
from multiprocessing.pool import ThreadPool

code = 'Code123' # just an example
server = socket.gethostbyname(socket.gethostname())
port_left = 65336
found = False

def connect(port):
    global port_left, code, server, found
    if found: return
    port_left -= 1
    try:
        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        client.connect((server, port))
        if client.recv(len(code)).decode('utf-8') == code:
            found = True
            return client
        else: client.close()
    except Exception as e:
        print(e, port_left)
    return None

pool = ThreadPool(10)
values = [('c', i) for i in set(pool.map(connect, range(1024, 65336))) if i]
client = dict(values).get('c')
pool.close()
pool.join()
print(client)

Is there a better way to achieve this goal or improve the performance of my existing code?


Solution

  • Not a direct answer, but too long for a comment.

    This is not the way random ports are expected to be used. They are used for the data connection in the FTP protocol that way (passive mode):

    • the client opens the control connection on a well known port (21)
    • it asks the server for a random data port through the control connection
    • it opens the data connection knowing its port

    Opening a connection on random ports should be avoided, because if the server does not answer immediately, the client has to wait for a timeout to decide whether the server was just busy or not there.

    So my advice if you want to use random ports is to keep one well known port on which the client will get the real random port.