15

1 回限りの HTTP サーバーを作成して単一のコールバックを処理しようとしていますが、Ruby で空いている TCP ポートを見つけるのに助けが必要です。

これは私がやっていることの骨組みです:

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

(最初の接続に標準入力をエコーし​​、その後終了します。)

リッスンする空きポートを自動的に見つけるにはどうすればよいですか?

これは、一意のジョブ ID でコールバックするリモート サーバーでジョブを開始する唯一の方法のようです。その後、このジョブ ID を照会してステータス情報を取得できます。元の設計者が、ジョブをスケジュールするときにジョブ ID を返すことができなかった理由はわかりません。複数のコールバックとの競合が発生する可能性があるため、単一のポートは使用できません。このようにして、ポートは +-5 秒間だけ使用されます。

4

6 に答える 6

70

ポート番号には 0 を渡します。これにより、システムはエフェメラル ポート範囲からポートを選択します。サーバーを作成したら、サーバーがバインドされているポートを含む addr を要求できます。

server = TCPServer.new('127.0.0.1', 0)
port = server.addr[1]
于 2008-10-14T15:00:57.977 に答える
3

すべてを 1 行で実行しようとしないと、実際には非常に簡単です :-/

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

これは、質問のスニペットと同じ(強い言葉)を達成します。

于 2008-10-14T11:34:40.047 に答える
-8

ランダムなポートで通信しないでください。デフォルトのものを選択し、構成可能にします。ランダム ポートはファイアウォールと互換性がありません。FTP はこれを行い、ファイアウォールのサポートは悪夢です。パケットを深く検査する必要があります。

于 2008-10-14T10:01:26.770 に答える
-9

すべてのポート > 5000 (たとえば) を順番に試すことができると思います。しかし、リッスンしているポートをクライアント プログラムにどのように伝えるのでしょうか。異なる環境間でスクリプトを移動する必要がある場合は、ポートを決定してから、簡単に構成できるようにする方が簡単に思えます。

HTTP の場合、標準ポートは 80 です。使用されている別のポートは 8080、880、および 8000 です。

于 2008-10-14T09:32:23.130 に答える