This part is some work of code analysis of CF.
First, let's look at the ../vcap/common/lib/vcap/common.rb which defines some interesting methods to use.
def self.grab_ephemeral_port
socket = TCPServer.new('0.0.0.0', 0)
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
Socket.do_not_reverse_lookup = true
port = socket.addr[1]
socket.close
return port
end
As we have had the basic knowledge of socket programming in last post, we can refer everything now from:
http://www.ruby-doc.org/stdlib-1.9.3/libdoc/socket/rdoc/index.html
new([hostname,] port) => tcpserver
Creates a new server socket bound to port.
If hostname is given, the socket is bound to it.
setsockopt(level, optname, optval)
Sets a socket option.
level is an integer, usually one of the SOL_ constants such asSocket::SOL_SOCKET, or a protocol level.
optname is an integer, usually one of the SO_ constants, suchas Socket::SO_REUSEADDR.
optval is the value of the option, it is passed to theunderlying setsockopt() as a pointer to a certain number of bytes. How this is done depends on the type:
Fixnum: value is assigned to an int, and a pointer to the int is passed,with length of sizeof(int).
true or false: 1 or 0 (respectively) is assigned to an int, and the int ispassed as for a Fixnum. Note that false must be passed, notnil.
String: the string's data and length is passed to the socket.
socketoption is an instance of Socket::Option
do_not_reverse_lookup = true # turn off reverse DNS resolution temporarily
port = socket.addr[1] # This will return the port? That means the addr[0] is host?
Based on the knowledge above. There's also a trick to get server IP and Client IP in ruby on rails:
Write the code in Controller
For Client IP:
request.remote_ip
@remote_ip = request.env["HTTP_X_FORWARDED_FOR"]
For Server IP:
require 'socket'
def local_ip
orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true # turn off reverse DNS resolution temporarily
UDPSocket.open do |s|
s.connect '64.233.187.99', 1
s.addr.last
end
ensure
Socket.do_not_reverse_lookup = orig
end
That is what CloudFoundry do in method ../common.rb#local_ip