Sockets provide a low-level interface for network communication. Ruby's Socket library offers both TCP (reliable, connection-oriented) and UDP (fast, connectionless) protocols for building network applications.
require 'socket'
# Create a basic socket
socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM)
puts socket.class # => Socket
TCPServer creates a server that listens for incoming TCP connections. It's perfect for building reliable, connection-oriented services.
require 'socket'
# Create a TCP server on port 3000
server = TCPServer.new('localhost', 3000)
puts "Server listening on port 3000..."
loop do
# Accept incoming connections
client = server.accept
# Read client request
request = client.read_nonblock(1024) rescue nil
puts "Received: #{request}"
# Send response
client.write("HTTP/1.1 200 OK\r\n\r\nHello from Ruby server!")
# Close connection
client.close
end
require 'socket'
server = TCPServer.new('localhost', 3000)
puts "Multi-threaded server listening on port 3000..."
loop do
Thread.start(server.accept) do |client|
begin
# Handle each client in separate thread
request = client.read_nonblock(1024) rescue ""
# Process request
response = process_request(request)
# Send response
client.write(response)
rescue => e
puts "Error handling client: #{e.message}"
ensure
client.close
end
end
end
def process_request(request)
case request
when /GET \/hello/
"HTTP/1.1 200 OK\r\n\r\nHello World!"
when /GET \/time/
"HTTP/1.1 200 OK\r\n\r\nCurrent time: #{Time.now}"
else
"HTTP/1.1 404 Not Found\r\n\r\nPage not found"
end
end
require 'socket'
# Connect to TCP server
client = TCPSocket.new('localhost', 3000)
# Send request
client.write("GET /hello HTTP/1.1\r\n\r\n")
# Read response
response = client.read
puts "Server response: #{response}"
client.close
UDP provides fast, connectionless communication. It's ideal for applications where speed is more important than guaranteed delivery.
require 'socket'
# Create UDP server
server = UDPSocket.new
server.bind('localhost', 3001)
puts "UDP server listening on port 3001..."
loop do
# Receive message and client info
message, client_info = server.recvfrom(1024)
puts "Received from #{client_info[2]}:#{client_info[1]}: #{message}"
# Send response back to client
response = "Echo: #{message}"
server.send(response, 0, client_info[2], client_info[1])
end
require 'socket'
# Create UDP client
client = UDPSocket.new
# Send message to server
message = "Hello UDP Server!"
client.send(message, 0, 'localhost', 3001)
# Receive response
response, server_info = client.recvfrom(1024)
puts "Server response: #{response}"
client.close
require 'socket'
# UDP broadcaster
broadcaster = UDPSocket.new
broadcaster.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
# Broadcast message
message = "Broadcast message: #{Time.now}"
broadcaster.send(message, 0, '255.255.255.255', 3002)
puts "Broadcasted: #{message}"
broadcaster.close
require 'socket'
server = TCPServer.new('localhost', 3000)
# Set non-blocking mode
server.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK)
clients = []
loop do
begin
# Try to accept new connection (non-blocking)
client = server.accept_nonblock
clients << client
puts "New client connected"
rescue IO::WaitReadable
# No new connections, continue
end
# Handle existing clients
clients.each do |client|
begin
data = client.read_nonblock(1024)
client.write("Echo: #{data}")
rescue IO::WaitReadable
# No data available
rescue EOFError
# Client disconnected
clients.delete(client)
client.close
end
end
sleep 0.1 # Prevent busy waiting
end
require 'socket'
server = TCPServer.new('localhost', 3000)
clients = [server]
loop do
# Wait for readable sockets
ready = IO.select(clients, nil, nil, 1.0)
next unless ready
ready[0].each do |socket|
if socket == server
# New client connection
client = server.accept
clients << client
puts "Client connected"
else
# Existing client has data
begin
data = socket.read_nonblock(1024)
socket.write("Received: #{data}")
rescue EOFError
# Client disconnected
clients.delete(socket)
socket.close
puts "Client disconnected"
end
end
end
end
require 'socket'
class ChatServer
def initialize(port = 3000)
@server = TCPServer.new('localhost', port)
@clients = []
puts "Chat server started on port #{port}"
end
def start
loop do
Thread.start(@server.accept) do |client|
@clients << client
client.write("Welcome to the chat!\n")
broadcast("A new user joined the chat\n", client)
handle_client(client)
end
end
end
private
def handle_client(client)
loop do
message = client.gets
break unless message
broadcast("User: #{message}", client)
end
rescue
# Client disconnected
ensure
@clients.delete(client)
client.close
broadcast("A user left the chat\n", client)
end
def broadcast(message, sender = nil)
@clients.each do |client|
next if client == sender
client.write(message) rescue nil
end
end
end
# Start the chat server
ChatServer.new.start
require 'socket'
require 'fileutils'
class FileTransferServer
def initialize(port = 3000)
@server = TCPServer.new('localhost', port)
puts "File transfer server started on port #{port}"
end
def start
loop do
Thread.start(@server.accept) do |client|
handle_file_transfer(client)
end
end
end
private
def handle_file_transfer(client)
# Read filename and size
filename = client.gets.chomp
filesize = client.gets.chomp.to_i
puts "Receiving file: #{filename} (#{filesize} bytes)"
# Receive file data
File.open("uploads/#{filename}", 'wb') do |file|
remaining = filesize
while remaining > 0
chunk = client.read([remaining, 1024].min)
file.write(chunk)
remaining -= chunk.length
end
end
client.write("File received successfully\n")
puts "File #{filename} received"
rescue => e
client.write("Error: #{e.message}\n")
ensure
client.close
end
end
# Ensure uploads directory exists
FileUtils.mkdir_p('uploads')
# Start the server
FileTransferServer.new.start
require 'socket'
require 'timeout'
class PortScanner
def initialize(host)
@host = host
end
def scan_port(port, timeout = 1)
Timeout::timeout(timeout) do
socket = TCPSocket.new(@host, port)
socket.close
true
end
rescue
false
end
def scan_range(start_port, end_port)
open_ports = []
(start_port..end_port).each do |port|
if scan_port(port)
open_ports << port
puts "Port #{port} is open"
end
end
open_ports
end
def threaded_scan(start_port, end_port, thread_count = 50)
ports = (start_port..end_port).to_a
open_ports = []
mutex = Mutex.new
threads = []
thread_count.times do
threads << Thread.new do
while port = mutex.synchronize { ports.shift }
if scan_port(port, 0.5)
mutex.synchronize { open_ports << port }
puts "Port #{port} is open"
end
end
end
end
threads.each(&:join)
open_ports.sort
end
end
# Example usage
scanner = PortScanner.new('localhost')
open_ports = scanner.threaded_scan(1, 1000)
puts "Open ports: #{open_ports}"
require 'socket'
require 'logger'
class RobustServer
def initialize(port = 3000)
@port = port
@logger = Logger.new(STDOUT)
@running = false
end
def start
@server = TCPServer.new('localhost', @port)
@running = true
@logger.info "Server started on port #{@port}"
trap('INT') { shutdown }
trap('TERM') { shutdown }
while @running
begin
client = @server.accept
Thread.new { handle_client(client) }
rescue => e
@logger.error "Error accepting client: #{e.message}"
end
end
end
private
def handle_client(client)
@logger.info "Client connected: #{client.peeraddr}"
begin
while line = client.gets
response = process_request(line.chomp)
client.puts response
end
rescue => e
@logger.error "Error handling client: #{e.message}"
ensure
client.close
@logger.info "Client disconnected"
end
end
def process_request(request)
case request
when 'time'
Time.now.to_s
when 'uptime'
"Server running for #{Time.now - @start_time} seconds"
else
"Unknown command: #{request}"
end
end
def shutdown
@logger.info "Shutting down server..."
@running = false
@server.close if @server
end
end
# Start the server
RobustServer.new.start
require 'socket'
require 'benchmark'
# Measure connection time
connection_time = Benchmark.measure do
socket = TCPSocket.new('google.com', 80)
socket.close
end
puts "Connection time: #{connection_time.real} seconds"
# Measure throughput
data = 'x' * 1024 # 1KB of data
iterations = 1000
throughput_time = Benchmark.measure do
server = TCPServer.new('localhost', 3000)
Thread.new do
client = server.accept
iterations.times { client.write(data) }
client.close
end
socket = TCPSocket.new('localhost', 3000)
received = 0
while chunk = socket.read(1024)
received += chunk.length
break if received >= data.length * iterations
end
socket.close
server.close
end
throughput = (data.length * iterations) / throughput_time.real / 1024 / 1024
puts "Throughput: #{throughput.round(2)} MB/s"
Watch and learn sockets & tcp/udp