English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Ruby Socket Programming

Ruby provides two levels of access to network services, at the bottom level you can access the operating system, which allows you to implement client and server support for basic sockets for connection-oriented and connectionless protocols.

Ruby supports unified network protocols for applications, such as FTP, HTTP, etc.

Whether it is high-level or low-level. Ruby provides some basic classes that allow you to interact with many protocols such as TCP, UDP, SOCKS, without being constrained at the network layer. These classes also provide auxiliary classes that allow you to easily read and write servers.

Next, let's learn how to do Ruby Socket programming

What are Sockets

When the application layer communicates with the transport layer, TCP and UDP may encounter the problem of providing concurrent services to multiple application processes at the same time. Multiple TCP connections or multiple application processes may need to transmit data through the same TCP protocol port. To distinguish different application processes and connections, many computer operating systems provide an interface called Socket for applications to interact with the TCP/IP protocol, to distinguish network communication and connections between different application processes.

There are mainly3Parameters: the destination IP address of communication, the transport layer protocol (TCP or UDP) used, and the port number used. The original meaning of Socket is 'socket'. By using this3The parameters combined together, bind a 'socket' to a Socket, so that the application layer can distinguish communication from different application processes or network connections through the socket interface, and realize concurrent data transmission service.

Sockets vocabulary analysis:

OptionsDescription
domainIndicate the protocol family used, usually PF_INET, PF_UNIX, PF_X25, etc.
typeSpecify the type of socket: SOCK_STREAM or SOCK_DGRAM, the Socket interface also defines raw sockets (SOCK_RAW), which allow programs to use low-level protocols
protocolIt is usually assigned 0.
hostnameIdentifier of the network interface:
  • A string, which can be a hostname or IP address

  • The string "<broadcast>", specifying the INADDR_BROADCAST address.

  • A string of length 0, specifying INADDR_ANY

  • An integer, representing the binary address in host byte order.

portPort is the number of the port, each server will listen to one or more port numbers for client connections, a port number can be a Fixnum port number, which includes the server name and port.

Simple client

We will write a simple client example using the given host and port below, the Ruby TCPSocket class provides an open method to open a socket.

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

Once you open a Socket connection, you can read it like an IO object, and after you're done, you need to close the connection like closing a file.

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

Online Example

require 'socket' # Sockets are part of the standard library
 
hostname = 'localhost'
port = 2000
 
s = TCPSocket.open(hostname, port)
 
while line = s.gets # Read each line of data from the socket
  puts line.chop # Print to the terminal
end
s.close # Close the socket

Simple service

Ruby can use the TCPServer class to write a simple service. The TCPServer object is a factory object for TCPSocket.

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

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

Online Example

require 'socket' # Obtain the socket standard library
 
server = TCPServer.open(2000) # The Socket listens on port 2000
loop { # Run the service indefinitely
  client = server.accept # Wait for a client connection
  client.puts(Time.now.ctime) # Send the time to the client
  client.puts "Closing the connection. Bye!"
  client.close # Close the client connection
}

Now, run the above code on the server to see the effect.

Multi-client TCP service

On the Internet, most services have a large number of client connections.

Ruby's Thread class can easily create multi-threaded services, where one thread handles client connections while the main thread waits for more connections.

Online Example

require 'socket' # Obtain the socket standard library
 
server = TCPServer.open(2000) # Socket listens on port 2000
loop { # Run the service indefinitely
  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 a new thread is created and immediately starts processing the request when server.accept receives a client connection. The main program immediately loops back and waits for a new connection.

Tiny Web Browser

We can use the socket library to implement any Internet protocol. The following code demonstrates how to retrieve the content of a web page:

Online Example

require 'socket'
 
host = 'www.oldtoolbag.com' # Web server
port = 80 # Default HTTP port
path = "/index.htm" # The address of the file to be retrieved
 
# This is an HTTP request
request = "GET #{path} HTTP/1.0\r\n\r\n"
 
socket = TCPSocket.open(host, port) # Connect to the server
socket.print(request) # Send the request
response = socket.read # Read the complete response
# Split response at the first blank line into headers and body
headers, body = response.split("\r\n\r\n", 2) 
print body # Output the result

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

The following code is equivalent to the previous code:

Online Example

require 'net/http' # The required libraries
host = 'www.oldtoolbag.com'           # The web server
path = '/index.htm'                 # The file we want 
 
http = Net::HTTP.new(host)          # Create connection
headers, body = http.get(path)      # Request file
if headers.code == "200"            # Check status code
  print body                        
else                                
  puts "#{headers.code} #{headers.message}" 
end

We have only introduced the application of Ruby sockets briefly above, for more documentation please see:Ruby Socket Library and Class Methods