Frage

Ich möchte auf localhost in Python einen beliebigen offenen TCP-Port erhalten. Was ist der einfachste Weg?

War es hilfreich?

Lösung

Meine aktuelle Lösung:

def get_open_port():
        import socket
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind(("",0))
        s.listen(1)
        port = s.getsockname()[1]
        s.close()
        return port

Nicht sehr schön und auch nicht 100% richtig, aber es funktioniert jetzt.

Andere Tipps

Der frei Port kann durch das Betriebssystem, ausgewählt durch Bindung eine Buchse an einem Port gefunden werden. Nachdem das Betriebssystem einen Port auswählt, kann der Buchse angeordnet sein. Diese Lösung ist jedoch auf Rennbedingungen nicht beständig ist -. In der kurzen Zeit zwischen der freie Portnummer bekommen und diesen Port andere Verfahren verwenden, können Sie diesen Port verwenden

def find_free_port():
    s = socket.socket()
    s.bind(('', 0))            # Bind to a free port provided by the host.
    return s.getsockname()[1]  # Return the port number assigned.

ich eigentlich die folgende in einem meiner Programme verwenden:

port = random.randint(10000,60000)

Natürlich ist dies auch anfälliger für Kollisionen als der Code, den Sie haben. Aber ich hatte nie ein Problem mit ihm. Der Punkt ist, zu einem bestimmten Zeitpunkt, die meisten dieser hohen Ports nicht verwendet werden, und wenn Sie nur eine zufällig wählen, einen Konflikt mit einem anderen Verfahren mit ziemlich unwahrscheinlich ist. Wenn Sie so etwas wie die Lösung tun Sie in Ihrer Antwort geschrieben (das Öffnen einer Buchse und packte seine Portnummer), dann ist es fast sicher, dass der Anschluss nicht zu Konflikten geht. Also, wenn dies etwas ist, dass Sie nur für sich selbst verwenden werden (als Gegensatz zu etwas Sie gehen an die Öffentlichkeit freizugeben), darüber nachzudenken, ob es lohnt sich mit einer wirklich kugelsicher Lösung kommen. Quoten sind, es wird nie einen Unterschied machen.

Motiviert durch Marcelo Cantos' Kommentar zu Ihrer Frage, werde ich hinzufügen, dass die Standardlösung in Fällen wie diesem ist es, den Prozess zu haben, der den Port zu binden, um es verwenden werden, und dann mit einem anderen Programm, dass die Informationen zu teilen, die es braucht . Typischerweise wird es etwas tun, wie eine temporäre Datei zu schreiben, die Port-Nummer zu einem gewissen Standard Ort im Dateisystem enthält. Da der Prozess mit dem Sie arbeiten nicht, dass tun, in gewissem Sinne mit dem, was Lösung Sie wird kommen ein bisschen wie ein Hack. Aber noch einmal, wenn es nur für den eigenen Gebrauch ist, das ist wahrscheinlich in Ordnung.

Dies ist meine Version, aber es ist nicht wirklich zufällig, wenn Sie einen Portbereich angeben. Dies wird auch von Rennbedingungen leiden, aber dies ist der beste Weg, ich weiß, wenn Sie den Port vor der Zeit wissen müssen.

import socket
import errno
import contextlib

reserved_ports = set()

def get_open_port(lowest_port = 0, highest_port = None, bind_address = '', *socket_args, **socket_kwargs):
    if highest_port is None:
        highest_port = lowest_port + 100
    while lowest_port < highest_port:
        if lowest_port not in reserved_ports:
            try:
                with contextlib.closing(socket.socket(*socket_args, **socket_kwargs)) as my_socket:
                    my_socket.bind((bind_address, lowest_port))
                    this_port = my_socket.getsockname()[1]
                    reserved_ports.add(this_port)
                    return this_port
            except socket.error as error:
                if not error.errno == errno.EADDRINUSE:
                    raise
                assert not lowest_port == 0
                reserved_ports.add(lowest_port)
        lowest_port += 1
    raise Exception('Could not find open port')

Die kurzlebigen Ports liegen im Wesentlichen in einem Bereich von 49.152 bis 65.535. wenn Sie Ports überprüfen, in größerem Bereich wollen, dann nur die Werte in randint ändern.

import pustil
from random import randint
def getfreeport():
    port = randint(49152,65535)
    portsinuse=[]
    while True:
        conns = pstuil.net_connections()
        for conn in conns:
            portsinuse.append(con.laddr[1])
        if port in portsinuse:
            port = randint(49152,65535)
        else:
            break
    return port
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top