Skip to content

Instantly share code, notes, and snippets.

@mikehale
Last active January 24, 2018 20:30
Show Gist options
  • Save mikehale/76086de658e6ff0d760e2fc25df9a498 to your computer and use it in GitHub Desktop.
Save mikehale/76086de658e6ff0d760e2fc25df9a498 to your computer and use it in GitHub Desktop.
Share file descriptors between processes on the same machine using unix domain sockets. Thanks to https://www.linuxquestions.org/questions/programming-9/how-to-share-socket-between-processes-289978/ for the inspiration.

Usage:

Open 2 terminals, run server.rb in one and client.rb in the other. The tcp socket file descriptor will be created in the client, passed to the server, and then used in the server to read from the HTTP server.

#!/usr/bin/env ruby
require 'socket'
socket_path = File.expand_path(File.dirname(__FILE__), '.sock')
UNIXSocket.open(socket_path) { |c|
# open a socket and pass the FD to the other process
s = TCPSocket.new 'heroku.com', 80
c.send_io STDOUT
c.send_io s
s.close # no longer needed here
p s.fileno
}
#!/usr/bin/env ruby
require 'socket'
socket_path = File.expand_path(File.dirname(__FILE__), '.sock')
File.delete(socket_path) if File.exist?(socket_path)
UNIXServer.open(socket_path) { |serv|
s = serv.accept
stdout = s.recv_io
heroku = TCPSocket.for_fd(s.recv_io.fileno)
p stdout.fileno
p heroku.fileno
p heroku.local_address
p heroku.remote_address
# Use the socket opened by client that we received above
heroku.write "GET / HTTP/1.1\r\n"
heroku.write "Host: heroku.com\r\n\r\n"
while (line = heroku.gets)
break if line.chomp == "0"
puts line
end
heroku.close
stdout.puts "done"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment