Ruby Socket
last modified October 18, 2026
In this article we show how to do Ruby network programming with sockets. Socket programming is low-level. The goal of this tutorial is to introduce network programming including these low-level details.
In programming, a socket is an endpoint of a communication between two programs running on a network. Sockets are used to create a connection between a client program and a server program.
Ruby's socket module provides an interface to the Berkeley sockets
API.
Network protocols
TCP/IP is a suite of protocols used by devices to communicate over the Internet and most local networks. TCP is more reliable, has extensive error checking, and requires more resources. It is used by services such as HTTP, SMTP, or FTP. UDP is much less reliable, has limited error checking, and requires less resources. It is used by services such as VoIP.
The Socket::SOCK_STREAM is used to create a socket for TCP and
Socket::SOCK_DGRAM for UDP.
Address families
When we create a socket, we have to specify its address family. Then we can only use addresses of that type with the socket.
- AF_UNIX, AF_LOCAL - Local communication
- AF_INET - IPv4 Internet protocols
- AF_INET6 - IPv6 Internet protocols
- AF_IPX - IPX - Novell protocols
- AF_BLUETOOTH - Wireless bluetooth protocols
- AF_PACKET - Low level packet interface
For the AF_INET address family, a pair (host, port) is specified.
The host is a string representing either a hostname in
Internet domain notation like example.com or an IPv4 address like
93.184.216.34, and port is an integer.
Ruby Socket.getnameinfo
The Socket.getnameinfo method obtains information about a socket
address.
#!/usr/bin/ruby require 'socket' p Socket.getnameinfo Socket.sockaddr_in 80, "127.0.0.1" p Socket.getnameinfo ["AF_INET", 80, "localhost"]
The example resolves the loopback address 127.0.0.1 and the name
localhost to node names and service names. Using the loopback
address keeps the example independent of network access and DNS.
require 'socket'
The Ruby socket API is in the socket module.
p Socket.getnameinfo Socket.sockaddr_in 80, "127.0.0.1" p Socket.getnameinfo ["AF_INET", 80, "localhost"]
A socket address is created either with Socket.sockaddr_in or
with an array containing the address family, port, and host name. To resolve
a public host such as example.com, pass that name in the same way;
the result depends on DNS and network access.
$ ./get_addr.rb ["localhost", "http"] ["localhost", "http"]
Socket.getifaddrs & Socket.ip_address_list
The Socket.getifaddrs returns an array of interface addresses and
the Socket.ip_address_list returns local IP addresses as an array.
#!/usr/bin/ruby require 'socket' pp Socket.getifaddrs p '----------------------------' pp Socket.ip_address_list
The example prints all local interfaces and IP addresses.
Ruby UDP socket example
UDP is a communication protocol that transmits independent packets over the network with no guarantee of arrival and no guarantee of the order of delivery. One service that used UDP is echo.
The Echo Protocol is a service in the Internet Protocol Suite defined in RFC 862. The Echo Protocol can use the TCP or the UDP on the port number 7. The server sends back an identical copy of the data it received.
$ cat /etc/services | grep echo | head -4 echo 7/tcp echo 7/udp echo 4/ddp # AppleTalk Echo Protocol
Port 7 is reserved for echo service.
Due to security concerns, the echo service is disabled in most cases. Instead, we use the small Ruby echo server shown in the client/server example below. Start it in one terminal:
$ ./echo_server.rb starting echo server
Then run the client in another terminal. It connects to localhost
on port 4444.
#!/usr/bin/ruby require 'socket' host = 'localhost' port = 4444 msg = ARGV[0] || "hello" s = UDPSocket.new s.connect host, port s.sendmsg msg + "\n" puts s.recv 20 s.close
The example sends a small message to the echo service. The message is echoed back.
s = UDPSocket.new
A new UDP socket is created with UDPSocket.new.
s.connect host, port
We connect to the host on the specified port.
s.sendmsg msg + "\n"
We send the message to the echo service with the sendmsg method.
puts s.recv 20
The recv method receives a message; its argument is maxlen, which
is the maximum number of bytes to receive.
s.close
We close the socket with close.
$ ./echo_client.rb hello $ ./echo_client.rb cau cau
Our messages are echoed back to us. You can watch the UDP traffic with the
tcpdump tool if you need to inspect the packets.
Ruby TCP socket example
TCP provides reliable, ordered, and error-checked delivery of a stream of octets (bytes) between applications running on hosts communicating via an IP network.
$ cat /etc/services | grep qotd qotd 17/tcp quote
Port 17 is reserved for the quote of the day service.
A quote of the day service is a useful debugging and measurement tool. The service simply sends a short message without regard to the input.
#!/usr/bin/ruby
require 'socket'
s = TCPSocket.new 'djxmmx.net', 17
s.send '', 0
puts s.recv(350).delete("\0")
s.close
The example creates a client program that connects to a QOTD service.
s = TCPSocket.new 'djxmmx.net', 17
A TCP/IP socket is created with TCPSocket.new. We provide a
hostname and the port number.
s.send '', 0
We send an empty message to the socket.
puts s.recv(350).delete("\0")
s.close
We receive the output, remove the trailing null byte, and close the socket.
$ ./qotd_client.rb "Oh the nerves, the nerves; the mysteries of this machine called man! Oh the little that unhinges it, poor creatures that we are!" Charles Dickens (1812-70)
The quote changes every day.
Ruby Socket HTTP HEAD request
A HEAD request is an HTTP GET request without a message body. The header of a request/response contains metadata, such as HTTP protocol version or content type.
#!/usr/bin/ruby require 'socket' s = TCPSocket.new 'example.com', 80 s.write "HEAD / HTTP/1.0\r\n" s.write "Host: example.com\r\n" s.write "User-Agent: Console Http Client\r\n" s.write "Accept: text/html\r\n" s.write "Accept-Language: en-US\r\n" s.write "Connection: close\r\n\r\n" res = s.read puts res s.close
In the example, we send a HEAD request to example.com.
s.write "HEAD / HTTP/1.0\r\n" s.write "Host: example.com\r\n" s.write "User-Agent: Console Http Client\r\n" s.write "Accept: text/html\r\n" s.write "Accept-Language: en-US\r\n" s.write "Connection: close\r\n\r\n"
A HEAD request is issued with the HEAD command followed by the
resource URL and HTTP protocol version. Note that the \r\n are
a mandatory part of the communication process. The details are described
in RFC 9110.
$ ./http_head.rb HTTP/1.1 200 OK Date: Sun, 18 Oct 2026 10:10:50 GMT Content-Type: text/html; charset=utf-8 Connection: close Server: cloudflare Last-Modified: Tue, 13 Oct 2026 20:08:28 GMT Allow: GET, HEAD Accept-Ranges: bytes Age: 8644 cf-cache-status: HIT CF-RAY: a4c6c16709676e91-BTS alt-svc: h3=":443"; ma=86400
Ruby Socket GET request
The HTTP GET method requests a representation of the specified resource. Requests using GET should only retrieve data.
#!/usr/bin/ruby require 'socket' s = TCPSocket.new 'example.com', 80 s.write "GET / HTTP/1.0\r\n" s.write "Host: example.com\r\n" s.write "Connection: close\r\n\r\n" res = s.read puts res s.close
The example reads the home page of example.com using a GET
request.
s.write "GET / HTTP/1.0\r\n" s.write "Host: example.com\r\n" s.write "Connection: close\r\n\r\n"
We write a simple GET request to the socket. The Host header is
required by many servers.
$ ./http_get.rb
HTTP/1.1 200 OK
Date: Sun, 18 Oct 2026 10:15:48 GMT
Content-Type: text/html; charset=utf-8
Connection: close
Server: cloudflare
Last-Modified: Tue, 13 Oct 2026 20:08:28 GMT
Allow: GET, HEAD
Accept-Ranges: bytes
Age: 8943
cf-cache-status: HIT
CF-RAY: a4c6c8b2acd6c258-BTS
alt-svc: h3=":443"; ma=86400
<!doctype html><html lang=en><head><meta charset=utf-8><link rel=icon href=data:,><meta name=viewport content="width=device-width,initial-scale=1"><title>Example Domain</title><style>html{color-scheme:light dark;background:light-dark(#eee,#222)}body{font:16px/1.6 system-ui,sans-serif;max-width:26em;margin:auto;padding:25vh 2em 2em;text-align:center}</style></head><body><p>This domain is for use in documentation examples without needing permission. This is not a service; avoid relying on it for testing and monitoring purposes.</p><script src=/s.js></script></body></html>
Ruby client/server example
In the following section, we create a UDP echo client and server.
#!/usr/bin/ruby
require 'socket'
puts 'starting echo server'
Socket.udp_server_loop 4444 do |data, src|
src.reply data
end
The echo server is created with Socket.udp_server_loop. It creates
a UDP/IP server on the given port and calls the block for each message received.
The server sends the message back to the client.
#!/usr/bin/ruby require 'socket' s = UDPSocket.new s.connect 'localhost', 4444 s.send "hello", 0 puts s.recv 50 s.close
The client sends a message to the echo server.
Ruby socket simple web server
The following example creates a simple web server.
#!/usr/bin/ruby
require 'socket'
port = (ARGV[0] || 8080).to_i
server = TCPServer.new port
p server
puts "server started on port #{port}"
loop do
client = server.accept
puts "Request: #{client.gets}"
client.print "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"
client.print "<html><body><h1>#{Time.now}</h1></body></html>\r\n"
client.close
end
The server sends the current time in the HTML output. The accept
method accepts an incoming connection. It returns a new TCPSocket object.
$ ./web_server.rb #<TCPServer:fd 5, AF_INET, 0.0.0.0, 8080> server started on port 8080
We start the server.
$ nc localhost 8080 GET / HTTP/1.1 200 OK Content-Type: text/html <html><body><h1>2026-10-18 12:10:58 +0200</h1></body></html>
We test the server with the nc tool.
In this article we have shown how to create simple networking programs with sockets in Ruby.
List all Ruby tutorials.