2009-06-04 9 views
8

Supongamos que deseo ejecutar un servicio TCP/IP en algún puerto para IPC. Como paso el número de puerto a los procesos con los que quiero comunicarme, el número de puerto no importa. ¿Cuál es la mejor manera de obtener un número de puerto aleatorio, alto (generalmente> 49152) que todavía está disponible en el sistema? ¿Hay algo en POSIX que pueda usar?Obtenga un número de puerto aleatorio alto que aún esté disponible

Sé que los servidores FTP lo necesitan con frecuencia.

Respuesta

-9

La única forma es recorrer el rango de puertos deseado, intentando vincular un socket a cada puerto de uno en uno hasta encontrar uno que sea exitoso.

+2

No, no es la única manera. La vinculación al puerto cero es otra manera, y una forma infinitamente mejor. QED – EJP

13

Si no especifica un número de puerto, el sistema operativo seleccionará automáticamente un número ephemeral port para usted.

De Choosing the Port Number:

Nuevo software de servidor debe esforzarse por evitar depender de un número de puerto específico, especialmente si se trata de software a nivel de usuario que no está inevitablemente ligada a un puerto bien conocido. Afortunadamente, esto se hace fácilmente solicitando el puerto 0, que indica al sistema que elija un número de puerto efímero.

+1

Sí, el puerto 0 permite que el sistema operativo elija un puerto aleatorio disponible para usted. Por otro lado, el uso del puerto 0 no le permite especificar un rango de puertos para que el sistema operativo seleccione. Si está detrás de un cortafuegos/enrutador, por ejemplo, puede ser más importante poder usar rangos de puertos. –

+1

@RemyLebeau Cualquier firewall configurado para permitir únicamente un rango de puertos de salida está mal configurado y debe corregirse. Como Socket API no es compatible con eso, impone una carga a las aplicaciones que no pueden cumplir, además de no tener ningún sentido desde el punto de vista de la seguridad. – EJP

+0

@EJP: supone que la vinculación de puertos solo se realiza para las conexiones * outbound *. FTP es un buen ejemplo de cuándo un cliente puede necesitar enlazar conectores para conexiones * entrantes *, para transferencias de modo activo. –

5

Los puertos efímeros pueden hacer eso. Su sistema operativo le asignará un puerto del grupo de puertos libres.

Hay algo de código C, BSD-licencia, haciendo esto here

En Python, puede especificar un par socket.AF_INET ('', 0) dirección para el mismo propósito, por ejemplo, sock.bind(('', 0))

+0

¿Qué función de Python deberíamos llamar con argumentos ('127.0.0.1', 0)? –

+1

@ Nordlöw - [bind] (http://docs.python.org/2/library/socket.html#socket.socket.bind) –

+0

Esta es la respuesta de Python: http://bit.ly/1oGG0O0 – yucer

0

Puede usar mi pequeña biblioteca C: https://github.com/yegor256/random-tcp-port

compilarlo y ejecutar en la máquina. Saldrá un puerto TCP aleatorio disponible.

+3

de inmediato estará disponible nuevamente para otra persona tan pronto como se cierre. Esto es completamente sin sentido. – EJP

+0

Pero esto es exactamente lo que sugirió algunas respuestas a continuación, y todas las otras torres también sugieren :) Mi biblioteca simplemente hace que sea más fácil obtener – yegor256

+1

Lo está haciendo mal. Asignar puertos aleatorios ya es parte del sistema; todo lo que tienes que hacer es solicitar el número de puerto 0 y obtendrás un puerto aleatorio que puedes obtener con 'getsockname'. Sin embargo, si cierras el conector, no tienes garantía de que ese número de puerto ephemereal antiguo aún esté disponible. – PSkocik

1

Si intenta vincularse al número de puerto 0, el sistema vinculará su socket a un puerto aleatorio "ephemereal". A continuación, puede obtener el puerto con getsockname (en C).

En Ruby:

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

Ephemereal? ¿Cuánto tiempo duraría? Espero hasta que el servidor se detenga. – yucer

+0

@yucer Significa que no es un número fijo asociado con un servicio fijo particular como 80 para HTTP. Todavía durará hasta que cierre o hasta que el sistema operativo lo cierre por usted cuando finalice su proceso. – PSkocik

+0

Creo que el constructor ha cambiado. Ver: http://bit.ly/1o9DDJb También el atributo addr ahora es server_address – yucer

Cuestiones relacionadas