2012-01-12 14 views
10

Necesito crear un programa que se comunique con otros programas en la misma computadora a través de sockets UDP. Leerá comandos de stdin, y algunos de estos comandos harán que se envíen/reciban paquetes sin detener la ejecución. He leído alguna información por ahí, pero ya que no estoy familiarizado con la programación del zócalo y la necesidad de hacer esto rápidamente, tengo las siguientes preguntas:Obtener puerto aleatorio para socket UDP

  1. que necesito para obtener un puerto no utilizado al azar para el programa para escuchar, y reservarlo para que otros programas puedan comunicarse con esto y también el puerto no está reservado por otro programa. También necesito almacenar el número de puerto en una variable para uso futuro.
  2. Dado que la comunicación se realiza a través de procesos en la misma máquina, me pregunto si puedo usar PF_LOCAL.

También sería bienvenido un ejemplo de código de la configuración de dicho socket, así como un ejemplo de envío/recepción de cadenas de caracteres.

+0

¿Para qué plataforma? –

+0

Sistema operativo Linux utilizando bibliotecas estándar – rabusmar

+1

¿Por qué comunicarse entre procesos utilizando un socket? ¿Es solo por el bien de hacerlo?;) – BlackBear

Respuesta

20

Llame al bind() especificando el puerto 0. Eso permitirá que el sistema operativo elija un puerto no utilizado. A continuación, puede usar getsockname() para recuperar el puerto elegido.

+0

Esta es una buena manera de hacerlo, pero ciertamente no sería una forma aleatoria de hacerlo. – dbeer

+1

Supongo que si quisieras un puerto verdaderamente aleatorio, podrías seguir intentando enlazar a ((rand()% 65535) +1) hasta que el enlace sea exitoso. – selbie

+2

Será aleatorio porque no sabrá qué puerto se elige hasta que la vinculación sea exitosa. La vinculación al puerto 0 permite que el sistema operativo seleccione el primer puerto disponible no utilizado. Si 'bind()' tiene éxito, se garantiza que tendrá un puerto que usted y nadie más utilizan. Sus requisitos establecidos no requieren que sea verdaderamente aleatorio, único y lo será. –

0

Si ser un puerto aleatorio es realmente importante, usted debe hacer algo como:

srand(time(NULL)); 
rand() % NUM_PORTS; // NUM_PORTS isn't a system #define 

A continuación, especifique ese puerto en lazo. Si falla, elija uno nuevo (no es necesario volver a inicializar el generador aleatorio. Si el puerto aleatorio no es importante, consulte la respuesta de Remy Lebeau.

+1

Debería realizar un seguimiento de los puertos que intentó, por lo que no intenta vincularlos nuevamente ya que fallaron la primera vez. –

+0

Es cierto, aunque la probabilidad de que repita puertos en la secuencia pseudoaleatoria antes de encontrar un puerto abierto es bastante baja. – dbeer

1

Respuesta de Remy Lebeau es bueno si necesita un puerto temporal No es tan bueno si necesita un puerto reservado persistente porque otro software también usa el mismo método para obtener un puerto (incluida la pila TCP del sistema operativo que necesita un nuevo puerto temporal para cada conexión).

Entonces podría suceder lo siguiente :

  1. usted llama se unen con 0 y getsockname() para obtener un puerto;
  2. luego SAVE I t en config (o en varias configuraciones) para usos futuros;
  3. software que necesita este puerto se inicia y vincula el puerto.

Luego tiene que p. Ej. reinicie el software:

  1. software detiene y desvincula el puerto: el puerto ahora puede ser devuelto por bind (0) y getsockname() nuevamente;
  2. p. La pila TCP necesita un puerto y vincula su puerto;
  3. El software
  4. no se puede iniciar porque el puerto ya está enlazado.

Por lo tanto, para "usos futuros" necesita un puerto que no está en el rango de puerto efímero (ese es el rango desde el cual bind (host, 0) devuelve un puerto).

Mi solución para este problema es la utilidad de línea de comandos port-for.

+2

Muy raramente, si alguna vez, necesitará recuperar un puerto efímero la primera vez y guardarlo para volver a usarlo en conexiones posteriores. He estado escribiendo código de socket por más de 10 años y nunca tuve la necesidad de hacerlo, ni una vez. Normalmente, utilizaría puertos efímeros todas las veces (y para los servidores, proporcionaría una forma de descubrir ese puerto de forma dinámica) o que el usuario especifique un puerto fijo en la configuración de la aplicación, en cuyo caso el usuario se asegurará de que el puerto esté siempre disponible para utilizar. –

+0

Si mi comprensión de la pregunta es correcta (especialmente la parte "1"), pregunta por esto. Sin embargo, este puede no ser el caso. El caso de uso no es hacer que el usuario se asegure de que el puerto esté siempre disponible, sino que haga que un software asegure que el puerto esté disponible. –

Cuestiones relacionadas