I'm trying to create a use-once HTTP server to handle a single callback and need help with finding a free TCP port in Ruby.
This is the skeleton of what I'm doing:
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
(It echoes standard input to the first connection and then dies.)
How can I automatically find a free port to listen on?
This seems to be the only way to start a job on a remote server which then calls back with a unique job ID. This job ID can then be queried for status info. Why the original designers couldn't just return the job ID when scheduling the job I'll never know. A single port cannot be used because conflicts with multiple callbacks may occur; in this way the ports are only used for +- 5 seconds.
Pass 0 in for the port number. This will cause the system to pick a port for you out of the ephemeral port range. Once you create the server, you can ask it for its addr, which will contain the port that the server is bound to.
server = TCPServer.new('127.0.0.1', 0)
port = server.addr[1]
It is actually quite easy when you don't try to do everything in one line :-/
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
This accomplishes (strong word) the same as the snippet in the question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With