python - 检查套接字端口是否可用

标签 python sockets tcp

情况:

我有一个应用程序,它有一个 TCP 服务器(基于 socketserver),我想测试它的功能。

我为自己创建了一个测试 mixin,我在每个测试用例中都使用它:

class AppProcessManagingMixin:
    _used_tcp_ports = set()

    def start_my_app(self):
        port = self._take_tcp_port()
        prepare_config_with_given_tcp_port(port)
        # use prepared config by subprocess below
        Popen([python_executable_path, my_app_name, ...).start()

    def _take_tcp_port(self):
        available_found = False
        while not available_found:
            port = random.randint(9000, 9999) # these ints are arbitrary here
            available_found = port not in self._used_tcp_ports
        self._used_tcp_ports.add(port)
        return port

    def stop_my_app(self):
        so_something_that_Im_sure_will_stop_my_app_after_a_few_seconds()

每个测试用例 setUp() 调用 self.start_my_app(),每个 tearDown() - self.stop_my_app( ),我可以放心地停止我的应用程序。我需要我的应用程序的许多实例(并且无法在类范围内的设置/拆卸中启动/停止应用程序),因为我的一些测试正在检查应用程序是否在以空工作目录开始的场景中运行良好(我只需要“空”应用程序实例用于那些测试)。

第二种方法 _take_tcp_port 有问题。在介绍它之前,我经常遇到已占用地址的问题(因为所有测试都尝试在同一端口上运行 TCP 服务器)。现在这种情况不常发生,但仍然会发生。

我知道它是系统相关的,几秒钟后端口将再次可用,但这会使自动化测试变得更加困难。

问题:

我如何检查某些地址(主机和端口)是否可用于 TCP 服务器?我想在 _take_tcp_port 中检查它,以确保测试不会因为应用实例在使用端口时出现问题而失败。

我做过的研究:

我浏览了以下谷歌搜索的第一页:

  • 检查端口是否开放python
  • 检查端口是否可用python
  • 发现可用端口

我发现的所有方法都是基于尝试获取套接字。问题是,如果我成功获得套接字,我可以确定这个端口是打开的,但因为我这样做了,所以我不能确定我的应用程序是否能够获得它。我需要没有副作用的东西。

平台

这需要是多平台的(至少是 Windows、Linux、MacOS)。它必须至少在 p3.3+ 中工作。如果“有一个库”就足够了;)

最佳答案

您无需手动扫描可用端口——操作系统会为您完成。只需在调用 bind() 时指定端口 0,操作系统就会选择一个。这通常对测试很有用——您可以使用端口 0 启动一个端点,让它询问系统它实际获得的端口 (getsockaddr),然后使用该端口号启动第二个端点。

关于python - 检查套接字端口是否可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21937533/

相关文章:

C套接字编程通过同一连接发送多个发送和接收

c# - 如何从客户端获取原始数据包?

linux - 我对 ERROR_PROTECTION_VIOLATION 感到困惑

c# - 通过 .Net Socket 发送/接收为串行通信构建的消息

python - super 初始化与父级.__init__

python - Pandas 对多次出现的复杂字符串进行分组和值计数

c - 如何确定客户端是否已连接到我的套接字?

python - 如何设置 Celery 来调用自定义 worker 初始化?

python - Eclipse PyDev 中的括号折叠

networking - 是否有任何协议(protocol)规范允许使用 TCP 或 UDP?