Jak se dostat na aktuální číslo portu v baňce?

hlasů
13

Pomocí baňky , jak mohu získat aktuální číslo portu, který baňky je připojen k? Chci začít server na náhodném portu pomocí portu 0, ale také musím vědět, který port jsem dál.

Upravit

Myslím, že jsem si našel práci kolem mého problému, i když to není odpověď na otázku. Mohu iterovat porty počínaje 49152 a pokusit se použít tento port, přes app.run(port=PORT). Dokážu to v bloku try catch, takže pokud dostanu Address already in usechybu, můžu zkusit další port.

Položena 23/02/2011 v 01:14
zdroj uživatelem
V jiných jazycích...                            


5 odpovědí

hlasů
0

Většina operačních systémů v těchto dnech mají příkaz s názvem netstat, který vám poskytne seznam všech portů, které jsou v současné době v provozu, stejně jako aplikace, které běží na nich, pokud se zeptáte dost pěkně. :)

Mělo by být docela snadné analyzovat s os.popennebo subprocessmodul.

Až na to, že byste mohli jen sledovat, které porty používáte začnete každý server ...

Také, pokud jste náhodou, že dělá to zevnitř požadavek http, mohli byste se podívat na SERVER_PORT cgi proměnné z WSGI prostředí.

Odpovězeno 23/02/2011 v 04:21
zdroj uživatelem

hlasů
1

Vazba na port 0 je správná. Že umožní, aby operační systém zvolit volný port mezi 1024 a 65535 pro vás.

Chcete-li načíst zvolený port, po navázání použít your_socket.getsockname()[1].

Takže vše, co potřebujete zjistit, jak získat přístup k zásuvku poslechu Flask používá.

socket.getsockname()docs: http://docs.python.org/library/socket.html#socket.socket.getsockname

Odpovězeno 23/02/2011 v 09:08
zdroj uživatelem

hlasů
29

Nelze snadno dostat k zásuvce serveru používá baňky, jak je to skrytý v interních nastavení standardní knihovny (Baňka používá Werkzeug, jehož vývoj serveru je založen na stdlib je BaseHTTPServer).

Nicméně, můžete vytvořit dočasný port sám a zavřete zásuvku, která ji vytváří, pak se tento port použít sami. Například:

# hello.py
from flask import Flask, request
import socket

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello, world! running on %s' % request.host

if __name__ == '__main__':
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('localhost', 0))
    port = sock.getsockname()[1]
    sock.close()
    app.run(port=port)

vám dá číslo portu, který chcete použít. Příklad běh:

$ python hello.py 
* Running on http://127.0.0.1:34447/

a na prohlížení na adrese http: // localhost: 34447 / , vidím

Ahoj světe! běží na localhost: 34447

ve svém prohlížeči.

Samozřejmě, je-li něco jiného používá tento port mezi vámi zavírání zásuvky a pak Baňka otevření zásuvky s tímto portem, že dostanete „adresy v použití“ omylem, ale můžete být schopni používat tuto techniku ​​ve svém prostředí.

Odpovězeno 23/02/2011 v 11:59
zdroj uživatelem

hlasů
2

Jak již bylo řečeno by @VinaySajip Baňka používat standardní serverový soket, ale nikdy přiřadit instanci do žádné proměnné, stačí postavit ji a volat serve_forever()v řadě.

Každopádně místo toho se snaží vytáhnout zásuvku z app baňky, jak řekl @ThiefMaster, můžeme zachytit bind_socket()hovor a přečetl adresu, aniž by se postarat o souběžné vytvoření zásuvky. Tady je moje řešení:

from flask import Flask, request
import socketserver

app = Flask("")

original_socket_bind = SocketServer.TCPServer.server_bind
def socket_bind_wrapper(self):
    ret = original_socket_bind(self)
    print("Socket running at {}:{}".format(*self.socket.getsockname()))
    # Recover original implementation
    socketserver.TCPServer.server_bind = original_socket_bind
    return ret

@app.route("/")
def hello():
    return 'Hello, world! running on {}'.format(request.host)

socketserver.TCPServer.server_bind = socket_bind_wrapper   #Hook the wrapper
app.run(port=0, debug=True)
Odpovězeno 22/12/2014 v 08:18
zdroj uživatelem

hlasů
0

Souhlasím s přijatou odpovědí, že

Nelze snadno dostat k zásuvce serveru používá baňky, jak je to skrytý v interních nastavení standardní knihovny (Baňka používá Werkzeug, jehož vývoj server je založen na stdlib je BaseHTTPServer).

Nicméně, právě jsem zjistil, že Werkzeug vystavuje možnost předat popisovač souboru pro použití jako je socket při spuštění werkzeug.serving.BaseWSGIServer(což je to, co baňka je run()funkce skončí dělá). Při použití této funkce je možné zvolit náhodný dostupný port a pak říci Werkzeug ji používat.

Zde je spuštění mé žádosti:

import logging
import pprint
import sys
from flask import Flask

applog = logging.getLogger(__name__)
applog.setLevel(logging.INFO)
app = Flask(__name__)

if __name__ == '__main__':

    app.config.from_object('myapp.default_settings')
    try:
        app.config.from_envvar('MYAPP_SETTINGS')
    except RuntimeError:
        applog.warning("MYAPP_SETTINGS environment variable not set or invalid. Using default settings.")

    # SERVER_NAME should be in the form of localhost:5000, 127.0.0.1:0, etc...
    # So, split on : and take the second element as the port
    # If the port is 0, we need to pick a random port and then tell the server to use that socket
    if app.config['SERVER_NAME'] and int(app.config['SERVER_NAME'].split(':')[1]) == 0:
        import socket, os

        # Chose a random available port by binding to port 0
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.bind((app.config['SERVER_NAME'].split(':')[0], 0))
        sock.listen()

        # Tells the underlying WERKZEUG server to use the socket we just created
        os.environ['WERKZEUG_SERVER_FD'] = str(sock.fileno())

        # Update the configuration so it matches with the port we just chose
        # (sock.getsockname will return the actual port being used, not 0)
        app.config['SERVER_NAME'] = '%s:%d' % (sock.getsockname())

    # Optionally write the current port to a file on the filesystem
    if app.config['CREATE_PORT_FILE']:
        with open(app.config['PORT_FILE'], 'w') as port_file:
            port_file.write(app.config['SERVER_NAME'].split(':')[1])

    applog.info("Running app on %s" % (app.config['SERVER_NAME']))
    applog.info("Active Settings:%s" % pprint.pformat(app.config, compact=True))
    app.run()

Obsah myapp.default_settings:

SERVER_NAME = '127.0.0.1:0'
PORT_FILE = 'current_port'
CREATE_PORT_FILE = True

Důležitou bit sem zapadá os.environ['WERKZEUG_SERVER_FD']. Werkzeug dívá na této proměnné prostředí v průběhu run_simplefunkce a pokud je definována, předá jej jako fdparametr make_serverfunkce. Toto nakonec se používá jako zásuvka pro komunikaci.

I když nemohu zaručit stabilitu tohoto přístupu (nevím, jak dobře podporován WERKZEUG_SERVER_FDproměnná prostředí) Raději to řešili tak daleko, protože:

  1. Nemám procházet řadou portů chytání výjimky, prostě jsem si první dostupný port přímo z operačního systému.
  2. Neexistuje žádná šance, můj vybrán náhodně portu dostane přijata mezi dobou, kdy jsem se vážou náhodný port, a když jsem spuštění aplikace, protože port jsem vázání je port moje žádost skončí používání.

Výše uvedený kód protokoluje také port používán a případně zapíše aktuální port používán k souboru určeného konfigurační volby.

Odpovězeno 24/08/2018 v 21:53
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more