186

我正在尝试使用进程间通信,因为我不知道如何在 Windows 下使用命名管道,所以我想我会使用网络套接字。一切都发生在本地。服务器能够在单独的进程中启动从属服务器并监听某个端口。奴隶做他们的工作并将结果提交给主人。我如何确定哪个端口可用?我假设我无法在端口 80 或 21 上监听?

我正在使用 Python,如果这样可以减少选择。

4

5 回答 5

261

不要绑定到特定端口。相反,绑定到端口 0:

import socket
sock = socket.socket()
sock.bind(('', 0))
sock.getsockname()[1]

然后操作系统将为您选择一个可用的端口。您可以使用 获取选择的端口sock.getsockname()[1],并将其传递给从属设备,以便它们可以连接回来。

sock是您创建的套接字,由socket.socket.

于 2009-09-02T00:14:14.930 回答
89

为了摘录这些家伙上面解释的内容:

import socket
from contextlib import closing

def find_free_port():
    with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
        s.bind(('', 0))
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        return s.getsockname()[1]
于 2017-08-15T09:58:22.090 回答
47

将套接字绑定到端口 0。将选择一个从 1024 到 65535 的随机空闲端口。getsockname()您可以使用之后检索选定的端口bind()

于 2009-09-02T00:12:53.603 回答
5

如果您只需要找到一个空闲端口供以后使用,这里有一个类似于先前答案的片段,但更短,使用socketserver

import socketserver

with socketserver.TCPServer(("localhost", 0), None) as s:
    free_port = s.server_address[1]

请注意,端口不能保证保持空闲,因此您可能需要将此代码段和使用它的代码放在一个循环中。

于 2020-05-08T17:57:57.847 回答
4

你可以在任何你想要的端口上监听;通常,用户应用程序应该监听 1024 及以上的端口(通过 65535)。如果您有可变数量的侦听器,主要的事情是为您的应用程序分配一个范围 - 例如 20000-21000 和CATCH EXCEPTIONS。这就是您将如何知道您的计算机上的端口是否不可用(换句话说,被另一个进程使用)的方式。

但是,在您的情况下,只要在绑定失败时打印错误消息,为侦听器使用单个硬编码端口就不会出现问题。

另请注意,您的大多数套接字(用于从属)不需要显式绑定到特定的端口号 - 只有等待传入连接的套接字(如此处的主节点)才需要成为侦听器并绑定到端口。如果在使用套接字之前没有为套接字指定端口,则操作系统将为套接字分配一个可用端口。当主机想要响应从机向它发送数据时,当侦听器接收到数据时,可以访问发送方的地址。

我想你会为此使用UDP吗?

于 2009-09-02T00:13:25.553 回答