在本地主机上,如何选择自由端口号?

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

我使用的是Python,如果这样可以减少选择的话。

166368 次浏览

Bind the socket to port 0. A random free port from 1024 to 65535 will be selected. You may retrieve the selected port with getsockname() right after bind().

You can listen on whatever port you want; generally, user applications should listen to ports 1024 and above (through 65535). The main thing if you have a variable number of listeners is to allocate a range to your app - say 20000-21000, and CATCH EXCEPTIONS. That is how you will know if a port is unusable (used by another process, in other words) on your computer.

However, in your case, you shouldn't have a problem using a single hard-coded port for your listener, as long as you print an error message if the bind fails.

Note also that most of your sockets (for the slaves) do not need to be explicitly bound to specific port numbers - only sockets that wait for incoming connections (like your master here) will need to be made a listener and bound to a port. If a port is not specified for a socket before it is used, the OS will assign a useable port to the socket. When the master wants to respond to a slave that sends it data, the address of the sender is accessible when the listener receives data.

I presume you will be using UDP for this?

Do not bind to a specific port. Instead, bind to port 0:

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

The OS will then pick an available port for you. You can get the port that was chosen using sock.getsockname()[1], and pass it on to the slaves so that they can connect back.

sock is the socket that you created, returned by socket.socket.

For the sake of snippet of what the guys have explained above:

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]

If you only need to find a free port for later use, here is a snippet similar to a previous answer, but shorter, using socketserver:

import socketserver


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

Note that the port is not guaranteed to remain free, so you may need to put this snippet and the code using it in a loop.