Endpoints

Sockets use IP addresses to route messages to specific hots. A host is identified by a unique IP address. DSN maps host names to IP address. When you ask DNS to resolve a host name it responds with an IP address.

Loopbacks

IP addresses don’t always refer to remote hosts. Sometimes you want to connect to your local host. Most loopback interfaces are a virtual interface, unlike the interface to your network card. With a loopback address your network is constrained to the local host.

localhost is the name of the loopback interface and the IP is usually 127.0.0.1. This is defined in /etc/hosts.

Ports

The combination of IP address and port number must be unique for each socket. You could have a socket with an IPv4 address listening on the same port as a socket with an IPv6 address. You cannot have two sockets with the same IPv4 address listening on the same port number.

The following is an example of the different kinds of sockets you can create. :INET implies and IPv4 address.

require 'socket'
Socket.new(:INET, :STREAM) # TCP socket
Socket.new(:INET, :DGRAM)  # UDP socket
Socket.new(:UNIX, :STREAM) # UNIX stream socket
Socket.new(:UNIX, :DGRAM)  # UNIX datagram socket

Connections

In order to create a connection you must have two sockets.

  1. initiator (client)
  2. listener (server)

A socket that listens is a server. A socket that initiates a connection is a client.

Server Lifecyle

  1. create
  2. bind
  3. listen
  4. accept
  5. close
require 'socket'

# create
server = Socket.new(:INET, :STREAM)
# bind
server.bind(Socket.pack_sockaddr_in(4481, '0.0.0.0'))
# listen with listen queue of 128 connections
server.listen(128)

loop do
  # accept
  connection, _ = server.accept
  # close
  connection.close
end

Another way to write the above is like this:

require 'socket'

Socket.tcp_server_loop(4481) do |connection|
  connection.close
end

Client Lifecyle

  1. create
  2. bind
  3. connect
  4. close
require 'socket'

# create
socket = Socket.new(:INET, :STREAM)
# bind to port in ephemeral range and connect
socket.connect(Socket.pack_sockaddr_in(80, 'google.com'))
# close
socket.close

An alternative way to write this is:

require 'socket'

Socket.tcp('google.com', 80) do |connection|
  connection.write "GET / HTTP/1.1\r\n"
  connection.close
end
comments powered by Disqus