2008-10-14 11 views
9

Estoy tratando de crear un servidor HTTP de uso único para manejar una única devolución de llamada y necesito ayuda para encontrar un puerto TCP libre en Ruby.¿Cómo se puede encontrar un puerto de servidor TCP gratuito usando Ruby?

Este es el esqueleto de lo que estoy haciendo:

require 'socket' 
t = STDIN.read 
port = 8081 
while s = TCPServer.new('127.0.0.1', port).accept 
    puts s.gets 
    s.print "HTTP/1.1 200/OK\rContent-type: text/plain\r\n\r\n" + t 
    s.close 
    exit 
end 

(Se hace eco de la entrada estándar a la primera conexión y después muere.)

¿Cómo puedo encontrar automáticamente un puerto libre para escuchar ¿en?

Esta parece ser la única forma de iniciar un trabajo en un servidor remoto que luego devuelve la llamada con una identificación de trabajo única. Esta ID de trabajo puede consultarse para obtener información de estado. Por qué los diseñadores originales no pudieron simplemente devolver la identificación del trabajo al programar el trabajo, nunca lo sabré. No se puede usar un solo puerto porque pueden producirse conflictos con múltiples devoluciones de llamada; de esta forma, los puertos solo se usan durante + - 5 segundos.

Respuesta

-7

Supongo que puede probar todos los puertos> 5000 (por ejemplo) en secuencia. ¿Pero cómo se comunicará con el programa del cliente qué puerto está escuchando? Parece más sencillo decidir sobre un puerto, y luego hacerlo fácilmente configurable, si necesita mover su script entre diferentes entornos.

Para HTTP, el puerto estándar es 80. puertos alternativos que he visto utilizados son 8080, 880 y 8000.

+0

Consulte el (nuevo) último párrafo de la pregunta. –

+1

Esta no debería ser la respuesta aceptada; ver http://stackoverflow.com/a/201528/3528 a continuación. –

-6

no se comunican en puertos aleatorios. Elija uno predeterminado y hágalo configurable. Los puertos aleatorios son incompatibles con los firewalls. FTP hace esto y el soporte de firewall es una pesadilla: tiene que inspeccionar los paquetes en profundidad.

+3

La pregunta era cómo encontrar un puerto libre para usar, no si es o no una buena idea usar un puerto aleatorio. – ZombieDev

+0

No todos los flujos de tráfico TCP/IP a través de firewalls. –

3

En realidad, es bastante fácil cuando no se trata de hacer todo en una sola línea: -/

require 'socket' 
t = STDIN.read 

port = 8080 # preferred port 
begin 
    server = TCPServer.new('127.0.0.1', port)  
rescue Errno::EADDRINUSE 
    port = rand(65000 - 1024) + 1024 
    retry 
end 

# Start remote process with the value of port 

socket = server.accept 
puts socket.gets 
socket.print "HTTP/1.1 200/OK\rContent-type: text/plain\r\n\r\n" + t 
socket.close 

Con esto se logran (palabra fuerte) el mismo que el fragmento de código en la pregunta.

+4

Solo para seleccionar nit ... Elegir aleatoriamente de esta manera es un ciclo ilimitado, y teóricamente puede ejecutarse durante un tiempo indefinido en un servidor; una situación que empeora cuanto más puertos ya están en uso. –

64

Pase 0 en para el número de puerto. Esto hará que el sistema elija un puerto para usted fuera del rango de puerto efímero. Una vez que haya creado el servidor, puede solicitar su addr, que contendrá el puerto al que está vinculado el servidor.

server = TCPServer.new('127.0.0.1', 0) 
port = server.addr[1] 
+0

Estoy usando un socket básico (no TCPSocket), que no tiene el método 'addr'. ¿Sabrías por casualidad cómo puedo obtener el puerto en este caso? – troelskn

+3

Respondiendo a mi propia pregunta, use 'socket.getsockname.unpack (" snA * ") [1]' – troelskn

Cuestiones relacionadas