NAME
Sidef::Types::Glob::SocketHandle - Socket handle interface for network programming
DESCRIPTION
This class implements a socket handle interface for network communication in Sidef. It provides methods for creating and managing network sockets, supporting both client and server operations over TCP/IP and other protocols. SocketHandle wraps Perl's socket functionality and provides a Sidef-friendly API for network programming.
SYNOPSIS
# Create a server socket
var server = Socket.new(Socket.PF_INET, Socket.SOCK_STREAM, Socket.IPPROTO_TCP)
server.bind(Socket.pack_sockaddr_in(8080, Socket.INADDR_ANY))
server.listen(5)
say "Server listening on port 8080..."
var client = server.accept
# Read from client
var data = client.readline
say "Received: #{data}"
# Send response
client.say("Hello from server!")
client.close
# Create a client socket
var sock = Socket.new(Socket.PF_INET, Socket.SOCK_STREAM, Socket.IPPROTO_TCP)
var addr = Socket.pack_sockaddr_in(80, Socket.inet_aton("example.com"))
sock.connect(addr)
sock.say("GET / HTTP/1.0\r\n\r\n")
say sock.slurp
sock.close
INHERITS
Inherits methods from:
* Sidef::Types::Glob::FileHandle
This means all file handle methods (like read, write, print, say, close, etc.) are available on socket handles as well.
METHODS
new
SocketHandle.new(domain, type, protocol)
Socket.new(domain, type, protocol)
Creates a new socket handle with the specified domain (address family), socket type, and protocol.
Parameters:
domain- Address family (e.g., Socket.PF_INET for IPv4, Socket.PF_INET6 for IPv6)type- Socket type (e.g., Socket.SOCK_STREAM for TCP, Socket.SOCK_DGRAM for UDP)protocol- Protocol number (e.g., Socket.IPPROTO_TCP, Socket.IPPROTO_UDP, or 0 for default)
Returns: A new SocketHandle object, or nil on failure.
Example:
var tcp_socket = Socket.new(Socket.PF_INET, Socket.SOCK_STREAM, Socket.IPPROTO_TCP)
var udp_socket = Socket.new(Socket.PF_INET, Socket.SOCK_DGRAM, Socket.IPPROTO_UDP)
Aliases: call
bind
socket.bind(address)
Binds the socket to a local address and port. This is typically used by server sockets before calling listen().
Parameters:
address- Packed socket address structure (created with Socket.pack_sockaddr_in or similar)
Returns: True on success, false on failure.
Example:
var sock = Socket.new(Socket.PF_INET, Socket.SOCK_STREAM, 0)
var addr = Socket.pack_sockaddr_in(8080, Socket.INADDR_ANY)
sock.bind(addr) || die "Cannot bind: #{$!}"
listen
socket.listen(queuesize)
Marks the socket as a passive socket that will accept incoming connections. Must be called after bind() and before accept().
Parameters:
queuesize- Maximum length of the queue of pending connections (typically 5-128)
Returns: True on success, false on failure.
Example:
sock.bind(addr)
sock.listen(5) || die "Cannot listen: #{$!}"
accept
socket.accept
Accepts an incoming connection on a listening socket. This blocks until a client connects.
Returns: A new SocketHandle object representing the client connection, or nil on failure.
Example:
var server = Socket.new(Socket.PF_INET, Socket.SOCK_STREAM, 0)
server.bind(Socket.pack_sockaddr_in(8080, Socket.INADDR_ANY))
server.listen(5)
loop {
var client = server.accept || next
var peer = Socket.unpack_sockaddr_in(client.getpeername)
say "Connection from #{Socket.inet_ntoa(peer[1])}:#{peer[0]}"
client.say("Welcome!")
client.close
}
connect
socket.connect(address)
Initiates a connection to a remote socket. This is typically used by client sockets.
Parameters:
address- Packed socket address structure of the remote endpoint
Returns: True on success, false on failure.
Example:
var sock = Socket.new(Socket.PF_INET, Socket.SOCK_STREAM, 0)
var addr = Socket.pack_sockaddr_in(80, Socket.inet_aton("192.168.1.1"))
sock.connect(addr) || die "Cannot connect: #{$!}"
send
socket.send(message, flags=0, to=nil)
Sends a message through the socket. For connected sockets (TCP), the to parameter is not needed. For connectionless sockets (UDP), to specifies the destination.
Parameters:
message- The data to send (string or bytes)flags- Optional flags for send operation (default: 0)to- Optional destination address for connectionless sockets
Returns: The number of bytes sent, or nil on error.
Example:
# TCP socket
var sent = sock.send("Hello, World!")
# UDP socket with destination
var addr = Socket.pack_sockaddr_in(9999, Socket.inet_aton("192.168.1.100"))
sock.send("UDP message", 0, addr)
recv
socket.recv(length, flags=0)
Receives data from the socket.
Parameters:
length- Maximum number of bytes to receiveflags- Optional flags for receive operation (default: 0)
Returns: The received data as a string, or nil on error.
Example:
var data = sock.recv(1024)
if (defined(data)) {
say "Received: #{data}"
}
getsockname
socket.getsockname
Returns the local address to which the socket is bound.
Returns: Packed socket address structure, or nil on failure.
Example:
var addr = sock.getsockname
if (defined(addr)) {
var (port, ip) = Socket.unpack_sockaddr_in(addr)
say "Local address: #{Socket.inet_ntoa(ip)}:#{port}"
}
getpeername
socket.getpeername
Returns the address of the peer (remote end) connected to this socket.
Returns: Packed socket address structure, or nil on failure.
Example:
var addr = sock.getpeername
if (defined(addr)) {
var (port, ip) = Socket.unpack_sockaddr_in(addr)
say "Peer address: #{Socket.inet_ntoa(ip)}:#{port}"
}
getsockopt
socket.getsockopt(level, optname)
Gets a socket option value.
Parameters:
level- Protocol level (e.g., Socket.SOL_SOCKET)optname- Option name (e.g., Socket.SO_REUSEADDR, Socket.SO_KEEPALIVE)
Returns: The option value, or nil on failure.
Example:
var reuse = sock.getsockopt(Socket.SOL_SOCKET, Socket.SO_REUSEADDR)
say "SO_REUSEADDR is #{reuse ? 'enabled' : 'disabled'}"
setsockopt
socket.setsockopt(level, optname, optval)
Sets a socket option value.
Parameters:
level- Protocol level (e.g., Socket.SOL_SOCKET)optname- Option name (e.g., Socket.SO_REUSEADDR, Socket.SO_KEEPALIVE)optval- Option value to set
Returns: True on success, false on failure.
Example:
# Enable address reuse (useful for servers)
sock.setsockopt(Socket.SOL_SOCKET, Socket.SO_REUSEADDR, 1) ||
die "Cannot set SO_REUSEADDR: #{$!}"
# Enable TCP keepalive
sock.setsockopt(Socket.SOL_SOCKET, Socket.SO_KEEPALIVE, 1)
shutdown
socket.shutdown(how)
Shuts down part or all of the socket connection.
Parameters:
how- How to shut down the socket:0 (SHUT_RD) - Further receives are disallowed
1 (SHUT_WR) - Further sends are disallowed
2 (SHUT_RDWR) - Further sends and receives are disallowed
Returns: True on success, false on failure.
Example:
# Finish sending data and close the write side
sock.shutdown(1)
# Read remaining data from the peer
var remaining = sock.slurp
# Close completely
sock.close
COMMON USAGE PATTERNS
TCP Server
var server = Socket.new(Socket.PF_INET, Socket.SOCK_STREAM, 0)
server.setsockopt(Socket.SOL_SOCKET, Socket.SO_REUSEADDR, 1)
server.bind(Socket.pack_sockaddr_in(8080, Socket.INADDR_ANY))
server.listen(10)
say "Server started on port 8080"
loop {
var client = server.accept || next
say "Client connected"
# Handle client in a fork or thread
client.say("Welcome to the server!")
var request = client.readline
say "Received: #{request}"
client.close
}
TCP Client
var sock = Socket.new(Socket.PF_INET, Socket.SOCK_STREAM, 0)
var addr = Socket.pack_sockaddr_in(80, Socket.inet_aton("example.com"))
sock.connect(addr) || die "Cannot connect: #{$!}"
sock.say("GET / HTTP/1.1")
sock.say("Host: example.com")
sock.say("Connection: close")
sock.say("")
say sock.slurp
sock.close
UDP Server
var sock = Socket.new(Socket.PF_INET, Socket.SOCK_DGRAM, 0)
sock.bind(Socket.pack_sockaddr_in(9999, Socket.INADDR_ANY))
say "UDP server listening on port 9999"
loop {
var data = sock.recv(1024)
defined(data) || next
var peer = sock.getpeername
var (port, ip) = Socket.unpack_sockaddr_in(peer)
say "Received from #{Socket.inet_ntoa(ip)}:#{port}: #{data}"
}
UDP Client
var sock = Socket.new(Socket.PF_INET, Socket.SOCK_DGRAM, 0)
var addr = Socket.pack_sockaddr_in(9999, Socket.inet_aton("192.168.1.100"))
sock.send("Hello, UDP server!", 0, addr)
var response = sock.recv(1024)
say "Response: #{response}" if defined(response)
sock.close
SEE ALSO
Sidef::Types::Glob::FileHandle - Parent class with I/O methods
Socket - Perl's Socket module documentation for constants and helper functions
AUTHOR
Daniel "trizen" Șuteu
LICENSE
This library is free software; you can redistribute it and/or modify it under the same terms as Sidef itself.