你能在不监听的情况下实例化一个 Python HTTP 服务器吗?

Can you instantiate a Python HTTP server without it listening?

我的环境是 Python 3.7 on Windows 10。我正在开发(非常)轻量级的 HTTP 服务器应用程序,其主要目的是测试执行 HTTP POST 请求。我找到了 Python 文档和其他几个解释使用 http.server 模块的基础知识的来源,因此获得一个正常运行的服务器并不难。

有一个细节我很难理解。我通过实验发现 HTTPServer 实例不会等到您调用 serve_forever() 方法才开始监听。相反,它会在您实例化后立即开始侦听指定端口。如果您尝试(例如)这个小脚本:

import time
from http.server import BaseHTTPRequestHandler,HTTPServer

class MyHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        pass

h1 = HTTPServer(('', 10123), MyHandler)
print('Server instantiated')

while (True):
    time.sleep(0.1)
    pass

它除了实例化服务器什么都不做,但对本地机器的检查显示脚本导致端口 10123 被绑定和监听:

C:\Dev_Python\HTTPServer>netstat -anp tcp

Active Connections

Proto  Local Address          Foreign Address        State
TCP    0.0.0.0:10123          0.0.0.0:0              LISTENING

我进一步搜索文档后发现,我可以通过访问 class 的 socket 对象来 'undo' 监听:

h1.socket.close()

...但我宁愿服务器一开始就没有开始监听,直到我希望它真正开始监听。

所以问题是:有没有办法覆盖这种行为,并在延迟它监听端口的同时实例化服务器?

bind_and_activate关键字参数,默认值为True,可以控制新建套接字绑定和激活。

尝试:

...
h1 = HTTPServer(('', 10123), MyHandler, bind_and_activate=False)
...

以后可以绑定激活:

...
try:
    h1.server_bind()
    h1.server_activate()
except:
    h1.server_close()
    raise
...