EventMachine – how to get client’s IP address

I’m using EventMachine in one of my projects. EM is robust library to handle all dirty stuff related to low level network activities.

However it is not very well documented. You can learn a lot from it’s sources, but I’m not (yet :) I hope) so good to crunch such library in 15 minutes in order to get how to accomplish some simple task. I was googling for help few times, and found very little resources. So I will share my fresh knowledge ;)

My server is UDP based, and implements custom network protocol. At some point I needed to get UDP packets source addresses.

Running such UDP server with EventMachine is quite easy:

EventMachine::run {
   EventMachine::open_datagram_socket $conf[:address], 
                                 $conf[:udp_port], CustomServer
}

module CustomServer
   def receive_data d
      pp get_peername[2,6].unpack "nC4"
   end
end

$conf is hash defined somewhere else with configuration data, value for key :address is string with IP address, and for :udp_port integer with port number to listen on.

CustomServer is a module, which EventMachine::open_datagram_socket mixes in EventMachine::Connection class and instantiate. One of methods from this class is receive_data, which is called for every UDP packet received, with packet payload as argument.

To get sockaddr structure from receive_data method, just call get_peername, which will return string with this structure. To extract just source port number and IP address You need take 6 bytes part starting from byte 3 (2 bytes for port number and 4 bytes for IP address, each octet encoded as a single byte). Example output: [50000, 192, 168, 248, 1] – packet came from 192.168.248.1:50000.

And thats it!

If You are interested in using EM, stay tuned and subscribe to my RSS feed if You haven’t done it already.

Join the Conversation

5 Comments

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.