Sockets 获取仍然可用的随机高端口号

Sockets 获取仍然可用的随机高端口号,sockets,posix,tcp,Sockets,Posix,Tcp,假设我想在IPC的某个端口上运行TCP/IP服务。当我将端口号传递给我想要与之通信的进程时,端口号并不重要。获取系统仍然可用的随机高(通常>49152)端口号的最佳方法是什么?POSIX中有什么我可以使用的吗 我知道FTP服务器经常需要这样做。唯一的方法是在所需的端口范围内循环,尝试一次将一个套接字绑定到每个端口,直到您找到一个成功的端口。如果您不指定端口号,操作系统将自动为您选择一个端口号 发件人: 新的服务器软件应尽量避免依赖于特定的端口号,特别是如果它是用户级软件,而不是不可避免地绑定到已

假设我想在IPC的某个端口上运行TCP/IP服务。当我将端口号传递给我想要与之通信的进程时,端口号并不重要。获取系统仍然可用的随机高(通常>49152)端口号的最佳方法是什么?POSIX中有什么我可以使用的吗


我知道FTP服务器经常需要这样做。

唯一的方法是在所需的端口范围内循环,尝试一次将一个套接字绑定到每个端口,直到您找到一个成功的端口。

如果您不指定端口号,操作系统将自动为您选择一个端口号

发件人:

新的服务器软件应尽量避免依赖于特定的端口号,特别是如果它是用户级软件,而不是不可避免地绑定到已知端口。幸运的是,这可以通过请求端口0轻松完成,该端口指示系统选择临时端口号


短暂的港口可以做到这一点。您的操作系统将从空闲端口池中为您分配一个端口

有一些C代码,BSD许可,正在这样做


在Python中,您可以为相同的目的指定
('',0)
socket.AF\u INET地址对,例如
sock.bind('',0))
您可以使用我的小型C库:


编译它并在您的机器上运行。它将输出一个可用的随机TCP端口。

如果您试图绑定到端口号0,系统将把您的套接字绑定到一个“临时”随机端口。 然后,您可以使用
getsockname
(C)获取端口

在ruby中:

s = TCPServer.new('localhost', 0) #You can also use nil instead of 0
s.addr[1] #The obtained port number

是的,端口0允许操作系统为您选择一个随机可用端口。另一方面,使用端口0不允许指定操作系统要从中选取的端口范围。例如,如果您位于防火墙/路由器后面,那么能够使用端口范围就变得更加重要。@RemyLebeau任何配置为只允许一系列出站端口的防火墙都配置错误,应该予以修复。由于套接字API不支持这一点,因此它给应用程序带来了无法满足的负担,而且从安全角度来看,这完全是毫无意义的。@EJP:您假设端口绑定只针对出站连接进行。FTP是一个很好的例子,说明客户端可能需要为入站连接绑定套接字以进行活动模式传输。我们应该使用参数('127.0.0.1',0')调用哪个Python函数?@Nordlöw-一旦退出,它将立即对其他人可用。这是完全没有意义的。但这正是你在下面提出的一些答案,以及所有其他提问者也提出的:)我的库只是让你更容易找到你做错了。分配随机端口已经是系统的一部分——您所要做的就是请求端口号0,然后您将获得一个随机端口,您可以使用
getsockname
获得该端口。但是,如果关闭套接字,则无法保证旧的临时端口号仍然可用。@yegor256是的,不分离绑定和查找随机端口,只绑定到端口0。@PSkocik如果需要分离绑定和查找怎么办?这就是我的工具的用途。不,这不是唯一的方法。绑定到端口0是另一种方式,也是一种更好的方式。QEDEphemereal?会持续多久?我希望直到服务器停止。@yucer这意味着它不是一个与特定的固定服务相关联的固定数字,比如HTTP的80。它将一直持续到你关闭或者当你的进程终止时操作系统为你关闭它。我认为构造函数已经改变了。请参阅:另外,addr属性现在是server_address@yucer红宝石!=python