Easy Tutorial
❮ Ruby Dbi Read Ruby Array ❯

Ruby Socket Programming

Ruby provides two levels of access to network services. At the lower level, you can access the operating system, which allows you to implement basic socket support for both connection-oriented and connectionless protocols.

Ruby also offers unified support for network protocols like FTP and HTTP for applications.

Whether at a high or low level, Ruby provides basic classes that allow you to interact with many protocols such as TCP, UDP, and SOCKS without being constrained at the network layer. These classes also offer helper classes to make reading and writing to servers easy.

Let's learn how to do Ruby Socket programming.


What are Sockets?

When the application layer communicates data through the transport layer, both TCP and UDP encounter the issue of providing concurrent services to multiple application processes. Multiple TCP connections or multiple application processes might need to transmit data through the same TCP port. To distinguish between different application processes and connections, many operating systems provide an interface called a socket for applications to interact with TCP/IP protocols, differentiating network communications and connections between different application processes.

Creating a socket mainly involves three parameters: the destination IP address, the transport layer protocol (TCP or UDP), and the port number. The term "socket" originally means "plug." By combining these three parameters and binding them to a "plug" (socket), the application layer can communicate with the transport layer through the socket interface, distinguishing communications from different application processes or network connections, and achieving concurrent data transmission services.

Sockets Glossary:

Option Description
domain Indicates the protocol family used, usually PF_INET, PF_UNIX, PF_X25, etc.
type Specifies the type of socket: SOCK_STREAM or SOCK_DGRAM. The socket interface also defines raw sockets (SOCK_RAW), allowing programs to use lower-level protocols.
protocol Typically set to 0.
hostname Identifier for the network interface: a string, which can be a hostname or IP address. <br> The string "<broadcast>" specifies the INADDR_BROADCAST address. <br> A zero-length string specifies INADDR_ANY. <br> An integer interpreted as a binary address in host byte order.
port The port number, each server listens on one or more port numbers for client connections. A port number can be a Fixnum port number, including the server name and port.

Simple Client

Below is a simple client example written for a given host and port. The Ruby TCPSocket class provides an open method to open a socket.

TCPSocket.open(hostname, port) opens a TCP connection.

Once you open a socket connection, you can read from it like an IO object. After completion, you need to close the connection like you would close a file.

The following example demonstrates how to connect to a specified host, read data from the socket, and finally close the socket:

Example

require 'socket'      # Sockets are in the standard library

hostname = 'localhost'
port = 2000

s = TCPSocket.open(hostname, port)

while line = s.gets   # Read lines from the socket
  puts line.chop      # Print to the terminal
end
s.close               # Close the socket

Simple Server

In Ruby, you can write a simple server using the TCPServer class. A TCPServer object is a factory for TCPSocket objects.

Now, use TCPServer.open(hostname, port) to create a TCPServer object.

Next, call the accept method of TCPServer, which waits until a client connects to the specified port and then returns a TCPSocket object representing the connection to that client.

Example

require 'socket'               # Get sockets from stdlib

server = TCPServer.open(2000)  # Socket to listen on port 2000
loop {                         # Infinite loop for the server to run
  client = server.accept       # Wait for a client to connect
  client.puts(Time.now.ctime)  # Send the time to the client
  client.puts "Closing the connection. Bye!"
  client.close                 # Close the client connection
}

Run the above code on the server to see the effect.


Multi-Client TCP Server

Most services on the internet have a large number of client connections.

Ruby's Thread class makes it easy to create multi-threaded services. One thread handles the client connection, while the main thread waits for more connections.

Example

require 'socket'                # Get sockets from stdlib

server = TCPServer.open(2000)   # Socket to listen on port 2000
loop {                          # Infinite loop for the server to run
  Thread.start(server.accept) do |client|
    client.puts(Time.now.ctime) # Send the time to the client
    client.puts "Closing the connection. Bye!"
    client.close                # Close the client connection
  end
}

In this example, the socket runs indefinitely, and when server.accept receives a client connection, a new thread is created and immediately starts processing the request. The main program immediately loops back and waits for new connections.


Tiny Web Browser

You can use the socket library to implement any internet protocol. The following code shows how to retrieve the content of a web page:

Example

require 'socket'

host = 'www.w3cschool.cc'     # Web server
port = 80                     # Default HTTP port
path = "/index.htm"           # The file we want

# This is the HTTP request
request = "GET #{path} HTTP/1.0\r\n\r\n"

socket = TCPSocket.open(host, port)  # Connect to server
socket.print(request)                # Send request
response = socket.read               # Read complete response
# Split response at first blank line into headers and body
headers, body = response.split("\r\n\r\n", 2)
print body                           # Display the body

To implement a web-like client, you can use libraries pre-built for HTTP like Net::HTTP.

Example

require 'net/http'                  # Library we need
host = 'www.w3cschool.cc'           # Web server
path = '/index.htm'                 # The file we want

http = Net::HTTP.new(host)          # Create a connection
headers, body = http.get(path)      # Request the file
if headers.code == "200"            # Check the status code
  print body                        
else                                
  puts "#{headers.code} #{headers.message}" 
end

The above examples are just a simple introduction to Ruby socket applications. For more documentation, please refer to: Ruby Socket Library and Class Methods

❮ Ruby Dbi Read Ruby Array ❯