2008-10-14 11 views
9

Próbuję utworzyć serwer HTTP jednorazowy do obsługi pojedynczego wywołania zwrotnego i potrzebuję pomocy w znalezieniu wolnego portu TCP w Ruby.Jak znaleźć wolny port serwera TCP za pomocą Ruby?

To jest szkielet, co robię:

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 

(To echa standardowe wejście do pierwszego połączenia, a następnie umiera.)

Jak mogę automatycznie znajdzie wolny port słuchać na?

To wydaje się być jedynym sposobem, aby rozpocząć pracę na zdalnym serwerze, który następnie oddzwania z unikalnym ID pracy. Ten identyfikator pracy może być następnie zapytany o informacje o stanie. Dlaczego oryginalni projektanci nie mogli po prostu zwrócić identyfikatora zadania podczas planowania pracy, której nigdy nie poznam. Nie można użyć pojedynczego portu, ponieważ mogą wystąpić konflikty z wieloma wywołaniami zwrotnymi; w ten sposób porty są używane tylko przez 5 sekund.

Odpowiedz

-7

Domyślam się, że możesz wypróbować kolejno wszystkie porty> 5000 (na przykład). Ale w jaki sposób przekażesz programowi klienta, jakiego portu słuchasz? Wydaje się, że łatwiej jest wybrać port, a następnie łatwo go skonfigurować, jeśli chcesz przenieść skrypt między różnymi środowiskami.

Dla HTTP, standardowy port to 80. porty alternatywne widziałem używane są 8080, 880 i 8000.

+0

Zobacz (nowy) ostatni akapit pytania. –

+1

To nie powinna być akceptowana odpowiedź; patrz http://stackoverflow.com/a/201528/3528 poniżej. –

-6

nie komunikują się na losowych portów. Wybierz domyślny i skonfiguruj go. Losowe porty są niezgodne z zaporami ogniowymi. FTP to robi, a obsługa zapory ogniowej jest koszmarem - musi dokładnie sprawdzać pakiety.

+3

Pytanie brzmiało, jak znaleźć wolny port do użycia, a nie to, czy warto używać losowego portu. – ZombieDev

+0

Nie cały ruch TCP/IP przepływa przez zapory. –

3

Jest to całkiem proste, jeśli nie starają się zrobić wszystko, co w jednej linii: -/

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 

realizuje ten (mocne słowo) takie same jak we fragmencie w pytaniu.

+4

Po prostu do wybrania nit ... Wybieranie losowe w ten sposób jest pętlą nieograniczoną i może teoretycznie działać przez nieokreślony czas na serwerze; sytuacja, która się pogarsza, im więcej portów już jest w użyciu. –

64

Przeprowadź 0 dla numeru portu. To spowoduje, że system wybierze dla ciebie port z efemerycznego zakresu portów. Po utworzeniu serwera możesz poprosić go o swój adres, który będzie zawierał port, do którego serwer jest związany.

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

Używam podstawowego Socket (nie TCPSocket), który nie ma metody 'addr'. Czy przypadkiem nie wiesz, jak mogę zdobyć port w tej sprawie? – troelskn

+3

Odpowiadając na moje własne pytanie, użyj 'socket.getsockname.unpack (" snA * ") [1]' – troelskn

Powiązane problemy