在localhost上,如何选择一个空闲端口号?

Ant*_* L. 145 python sockets port ipc

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

我正在使用Python,如果这会减少选择.

谢谢!

mar*_*k4o 211

不绑定到特定端口,或绑定到端口0,例如sock.bind(('', 0)).操作系统将为您选择一个可用的端口.您可以获取使用的端口sock.getsockname()[1],并将其传递给从属设备,以便它们可以连接回来.

  • 你如何将号码传递给奴隶?对我来说听起来像鸡和鸡蛋的问题. (8认同)
  • 有关`sock.bind(('',0))的示例,请参见http://stackoverflow.com/a/2838309/3538289. (4认同)
  • 如果slave是在绑定后创建的,你可以在创建它们时将其作为参数传递。或者,您可以将其写入一些共享内存或两者都可以访问的文件,或者通过某个众所周知的端口号访问的中央服务器可以跟踪它。 (2认同)
  • 什么是“袜子”?你能展示一个带有导入声明的完整示例吗? (2认同)

Hav*_*ard 38

将套接字绑定到端口0.将选择1024到65535之间的随机空闲端口.您可以在getsockname()之后立即检索所选端口bind().


saa*_*aaj 36

为了上述人员解释的片段:

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]
Run Code Online (Sandbox Code Playgroud)

  • 还可以添加以下内容,以便在return语句之前快速重用该端口:`s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)` (3认同)
  • 如果在本地主机上:也许s.bind(('本地主机,0))更好 (2认同)
  • @jonEbird 在这种情况下 `socket.SO_REUSEADDR` 真的有帮助吗?根据我的阅读,仅与尝试绑定的套接字具有“SO_REUSEADDR”相关,并且是否在延迟套接字上设置该标志无关。 (2认同)

Mih*_*otă 11

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

import socketserver

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

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

  • 该解决方案更简单并且意味着更少的代码,但它也比接受的答案慢得多。接受的答案给出 -> 20.2 µs ± 1.5 µs 每个循环(7 次运行的平均值 ± 标准偏差,每次 10,000 个循环) 该解决方案给出 -> 191 µs ± 3.41 µs 每个循环(7 次运行的平均值 ± 标准偏差,每个 10,000 次循环)``` (4认同)