2009-09-02 31 views
110

Estoy tratando de jugar con la comunicación entre procesos y dado que no podía entender cómo usar named pipes en Windows, pensé que usaría sockets de red. Todo sucede localmente El servidor puede ejecutar esclavos en un proceso separado y escucha en algún puerto. Los esclavos hacen su trabajo y envían el resultado al maestro. ¿Cómo averiguo qué puerto está disponible? ¿Supongo que no puedo escuchar en el puerto 80 o 21?En localhost, ¿cómo selecciono un número de puerto libre?

Estoy usando Python, si eso reduce las opciones.

Gracias!

+1

Por cierto, si usted acaba de recoger un número de puerto aleatorio o aleatorio-ish (preferiblemente mayor de 1024), probablemente estará disponible . Incluso puede usar el puerto 80 o 21 o lo que sea, siempre que ningún otro programa esté escuchando. En un momento dado, en un sistema normal, solo una pequeña fracción de puertos está en uso. –

+17

Elegir un puerto aleatorio no es una buena idea, deje que el sistema operativo elija uno para usted. – Corehpf

+0

En POSIX: http://stackoverflow.com/questions/913501/how-to-let-kernel-choose-a-port-number-in-the-range-1024-5000-in-tcp-socket-pr –

Respuesta

170

No se vincule a un puerto específico ni se vincule al puerto 0, p. sock.bind(('', 0)). El sistema operativo seleccionará un puerto disponible para usted. Puede obtener el puerto que se eligió utilizando sock.getsockname()[1] y pasarlo a los esclavos para que puedan volver a conectarse.

+2

Consulte http://stackoverflow.com/a/2838309/3538289 para ver un ejemplo de 'sock.bind (('', 0))' – cevaris

+4

¿Cómo transfiere el número a los esclavos? Suena como un problema de huevo y pollo para mí. – Sebastian

+0

Si los esclavos se crean después del enlace, puede pasarlo como parámetro al crearlos. Alternativamente, podría escribirlo en alguna memoria compartida o en un archivo al que ambos puedan acceder, o un servidor central al que se acceda a través de un número de puerto conocido podría hacer un seguimiento de ello. – mark4o

35

Enlaza el socket al puerto 0. Se seleccionará un puerto libre aleatorio de 1024 a 65535. Puede recuperar el puerto seleccionado con getsockname() justo después de bind().

2

Puede escuchar en cualquier puerto que desee; en general, las aplicaciones de usuario deben escuchar los puertos 1024 y superiores (a través de 65535). Lo principal si tiene un número variable de oyentes es asignar un rango a su aplicación, digamos 20000-21000 y EXCEPCIONES DE CAPTURA. Así es como sabrá si un puerto es inutilizable (usado en otro proceso, en otras palabras) en su computadora.

Sin embargo, en su caso, no debería tener un problema al usar un solo puerto codificado duro para su oyente, siempre y cuando imprima un mensaje de error si falla la vinculación.

Tenga en cuenta también que la mayoría de sus sockets (para los esclavos) no necesitan estar explícitamente vinculados a números de puerto específicos: solo los sockets que esperan conexiones entrantes (como su maestro aquí) necesitarán ser escuchados y enlazados a un puerto. Si no se especifica un puerto para un socket antes de usarlo, el sistema operativo asignará un puerto utilizable al socket. Cuando el maestro quiere responder a un esclavo que le envía datos, la dirección del remitente es accesible cuando el oyente recibe datos.

Supongo que usará UDP para esto?

6

En aras de fragmento de lo que los chicos han explicado anteriormente:

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)) 
     return s.getsockname()[1] 
+0

si en localhost: tal vez 's.bind (('localhost', 0))' es mejor – codeskyblue

Cuestiones relacionadas