我正在尝试进行进程间通信,并且由于无法弄清楚如何在Windows下使用命名管道,因此我认为我将使用网络套接字。一切都发生在本地。服务器能够在单独的进程中启动从属服务器,并在某些端口上进行侦听。奴隶完成工作并将结果提交给主人。如何确定哪个端口可用?我假设我无法在端口80或21上收听?
我正在使用Python,如果这样做会减少选择的余地。
谢谢!
我正在尝试进行进程间通信,并且由于无法弄清楚如何在Windows下使用命名管道,因此我认为我将使用网络套接字。一切都发生在本地。服务器能够在单独的进程中启动从属服务器,并在某些端口上进行侦听。奴隶完成工作并将结果提交给主人。如何确定哪个端口可用?我假设我无法在端口80或21上收听?
我正在使用Python,如果这样做会减少选择的余地。
谢谢!
Answers:
为了简要说明上面的解释:
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]
s.bind(('localhost', 0))
更好
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
socket.SO_REUSEADDR
在这种情况下真的有帮助吗?据我了解,尝试绑定的套接字具有唯一的意义,SO_REUSEADDR
与是否在持久套接字上设置该标志无关紧要。
您可以在任何端口上侦听;通常,用户应用程序应侦听端口1024及更高端口(通过65535)。如果您的侦听器数量可变,那么最主要的事情就是为您的应用分配一个范围-例如20000-21000和CATCH EXCEPTIONS。这样,您将知道计算机上端口是否不可用(换句话说,由另一个进程使用)。
但是,就您而言,只要绑定失败时打印错误消息,就可以为侦听器使用单个硬编码端口,这不会有问题。
还要注意,您的大多数套接字(用于从属)不需要显式绑定到特定的端口号-仅需要将等待传入连接的套接字(例如此处的主机)设置为侦听器并绑定到端口。如果在使用套接字之前未为端口指定端口,则操作系统将为该套接字分配可用端口。当主机希望响应从机发送数据时,当侦听器接收数据时,可以访问发送者的地址。
我想您将为此使用UDP?
如果您只需要找到一个空闲端口供以后使用,这是一个类似于先前答案的代码段,但使用socketserver则更短:
import socketserver
with socketserver.TCPServer(("localhost", 0), None) as s:
free_port = s.server_address[1]
请注意,不能保证端口保持空闲状态,因此您可能需要将此代码段和使用它的代码放入循环中。