2008-10-14 6 views
9

Ich versuche, einen Einmal-HTTP-Server zu erstellen, um einen einzelnen Rückruf zu verarbeiten, und brauche Hilfe bei der Suche nach einem freien TCP-Port in Ruby. Wie finden Sie einen freien TCP-Server-Port mit Ruby?

Dies ist das Skelett, was ich tue:

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 

(Es spiegelt die Standardeingabe in der ersten Verbindung und dann stirbt.)

Wie kann ich automatisch einen freien Port finden hören auf?

Dies scheint die einzige Möglichkeit zu sein, einen Job auf einem Remote-Server zu starten, der dann mit einer eindeutigen Job-ID zurückruft. Diese Job-ID kann dann nach Statusinformationen abgefragt werden. Warum konnten die ursprünglichen Designer nicht einfach die Job-ID zurückgeben, wenn sie den Job planen, den ich nie erfahren werde. Ein einzelner Port kann nicht verwendet werden, da Konflikte mit mehreren Callbacks auftreten können. Auf diese Weise werden die Ports nur für + - 5 Sekunden verwendet.

Antwort

-7

Ich denke, Sie könnten alle Ports> 5000 (zum Beispiel) in der Reihenfolge versuchen. Aber wie werden Sie dem Client-Programm mitteilen, welchen Port Sie gerade hören? Es scheint einfacher zu sein, sich für einen Port zu entscheiden und ihn dann leicht konfigurierbar zu machen, wenn Sie Ihr Skript zwischen verschiedenen Umgebungen verschieben müssen.

Für HTTP, der Standard-Port ist 80. Alternative Ports i verwendet haben gesehen, sind 8080, 880 und 8000.

+0

Siehe (neuen) letzten Absatz der Frage. –

+1

Dies sollte nicht die akzeptierte Antwort sein; siehe http://stackoverflow.com/a/201528/3528 unten. –

-6

nicht auf zufälligen Ports kommunizieren Sie. Wählen Sie einen Standard und machen Sie es konfigurierbar. Zufällige Ports sind mit Firewalls nicht kompatibel. FTP tut dies und die Firewall-Unterstützung ist ein Albtraum - es muss Pakete gründlich untersuchen.

+3

Die Frage war, wie man einen freien Port findet, nicht ob oder ob es eine gute Idee ist, einen zufälligen Port zu verwenden. – ZombieDev

+0

Nicht alle TCP/IP-Datenströme fließen durch Firewalls. –

3

Es ist eigentlich ganz einfach, wenn Sie nicht versuchen, alles in einer Zeile zu tun: -/

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 

Dies erreicht (starke Wort) die gleiche wie die Schnipsel in der Frage.

+4

Nur zum Nit-Pick ... Das zufällige Auslesen ist eine unbeschränkte Schleife und kann theoretisch für eine unbestimmte Zeit auf einem Server laufen; eine Situation, die umso schlimmer wird, je mehr Ports bereits genutzt werden. –

64

Geben Sie 0 in für die Portnummer ein. Dies führt dazu, dass das System einen Port für Sie aus dem kurzlebigen Port-Bereich auswählt. Sobald Sie den Server erstellt haben, können Sie ihn nach seiner Adresse fragen, die den Port enthält, an den der Server gebunden ist.

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

Ich benutze einen Basis-Socket (nicht TCPSocket), der nicht die 'addr'-Methode hat. Würdest du zufällig wissen, wie ich in diesem Fall den Hafen bekommen kann? – troelskn

+3

Beantworten Sie meine eigene Frage mit 'socket.getsockname.unpack (" snA * ") [1]' – troelskn