我可以让CherryPy找到自己的可用端口吗?

时间:2013-12-12 01:39:56

标签: python cherrypy

我在同一台机器上运行许多Web服务器以进行测试。我不想处理服务器端口冲突,而是让服务器只是向操作系统询问可用端口,然后告诉我他们得到了什么。

我可以通过登录到控制台或写入指定的临时文件(不确定)将端口传回调用者,但知道端口号是棘手的部分。

目前,基于WSGI的服务器正在推出:

  cherrypy.quickstart(dev_server, config=_GetConfig(options))

配置将包含以下内容:

{ 'global':
                  { <snip>
                    'server.socket_host': '0.0.0.0',
                    'server.socket_port': int(options.port)
                  },
   <snip>
}

有没有办法用CherryPy做到这一点?

我假设我可以将端口设置为“0”以自动选择它,但这并没有让我有办法报告它。

2 个答案:

答案 0 :(得分:3)

基本理念是:

  • 绑定到端口0。
  • 询问套接字到底是哪个端口。
  • 以某种方式报告该端口。

第一部分主要取决于您如何构建,启动和配置服务器。 CherryPy非常灵活,细节会根据您的使用方式而有所不同。

第二部分要求您使用某种机制来编写启动服务器的顶级代码,在没有任何代码的情况下自动启动它们的机制之一。这是因为,在启动服务器之前,您需要手动bind服务器来获取其套接字。一旦你有了一个创建和绑定的套接字,getsockname将为你提供它最终绑定的地址和端口。

第三部分显然可以像你想要的一样容易或困难。


这是一个简单的例子,您甚至可以从交互式解释器中做到这一点:

def app(env, start):
    start('200 OK', [('Content-type', 'text/plain')])
    return ['Hello, world!']
server = cherrypy.wsgiserver.CherryPyWSGIServer(('0.0.0.0', 0), app,
                                                server_name='localhost')
server.bind(socket.AF_INET, socket.SOCK_STREAM)
addr, port = server.socket.getsockname()
print(port)
server.start()

您可能还想查看cherrypy.process.servers及其ServerAdapter,它可以让您从一个地方管理多个服务器,而不是拥有一堆必须手动协调的独立服务器

答案 1 :(得分:0)

如果您使用的是CherryPy的内置服务器,则可以使用cherrypy.server.bound_addr检查它实际在侦听的端口。

文档说:

属性 bound_addr

绑定地址,或者如果它是临时端口且套接字已 绑定,返回实际的端口绑定。

使用此示例:

def start():
    cherrypy.config.update({
        'server.socket_port': 0,
    })
    cherrypy.tree.mount(MyApp(), '', {})

    cherrypy.engine.signals.subscribe()
    cherrypy.engine.start()
    _host, port = cherrypy.server.bound_addr

    # Do something with the port here
    ...

    cherrypy.engine.block()