【问题标题】:Can you instantiate a Python HTTP server without it listening?你可以在没有监听的情况下实例化 Python HTTP 服务器吗?
【发布时间】:2019-12-20 20:25:22
【问题描述】:

我的环境是 Windows 10 上的 Python 3.7。我正在开发(非常)轻量级 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

我在进一步搜索文档时发现,我可以通过访问类的 socket 对象来“撤消”此侦听:

h1.socket.close()

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

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

【问题讨论】:

  • 如果你不介意我问,你为什么要延迟收听?
  • 我将 HTTP 服务器用作主机模拟器,以测试移动计算机应用程序。因此,我想要解决的测试用例包括连接问题——例如移动计算机应用程序尝试连接以提交 GET/POST/whatever,但主机不可用或只是不听。这让我可以确保移动应用程序优雅地处理该场景,例如为用户提供合理的超时和可理解的错误消息。

标签: python-3.x httpserver


【解决方案1】:

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

试试:

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

您可以稍后绑定并激活它:

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

【讨论】:

  • 完美运行。从这里我可以访问h1.socket 对象并使用普通的bind/listen/close 方法来控制服务器是否正在侦听。
猜你喜欢
  • 1970-01-01
  • 2015-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-08
  • 2020-09-29
相关资源
最近更新 更多