NAME

Sidef::Types::Glob::Socket - Socket networking interface for Sidef

DESCRIPTION

The Socket class provides a comprehensive interface to socket networking operations in Sidef. It wraps the functionality of Perl's Socket module, enabling network communication using various protocols including TCP, UDP, and Unix domain sockets. This class supports both IPv4 and IPv6 addressing, multicast operations, and provides utilities for address resolution and conversion.

SYNOPSIS

# Create a TCP client socket
var sock = Socket()
sock.open(:PF_INET, :SOCK_STREAM, 0)

# Resolve a hostname
var host_info = Socket.gethostbyname('www.example.com')
say host_info

# Pack a socket address
var port = 80
var addr = Socket.inet_aton('127.0.0.1')
var sockaddr = Socket.pack_sockaddr_in(port, addr)

# Create a socket pair for IPC
var (reader, writer) = (nil, nil)
Socket.socketpair(reader, writer, :PF_UNIX, :SOCK_STREAM, 0)

INHERITS

Inherits methods from:

* Sidef::Object::Object

METHODS

new

Socket.new()
Socket()

Creates and returns a new Socket object. This is the constructor for the Socket class.

Example:

var sock = Socket()
var sock2 = Socket.new()

open

sock.open(domain, type, protocol)

Opens a socket with the specified domain (address family), type, and protocol. Returns true on success, false on failure.

Parameters:

  • domain - Address family (e.g., :PF_INET for IPv4, :PF_INET6 for IPv6, :PF_UNIX for Unix domain)

  • type - Socket type (e.g., :SOCK_STREAM for TCP, :SOCK_DGRAM for UDP)

  • protocol - Protocol number (usually 0 to let the system choose)

Example:

var sock = Socket()
sock.open(:PF_INET, :SOCK_STREAM, 0) || die "Cannot open socket: #{$!}"

socketpair

Socket.socketpair(socket1, socket2, domain, type, protocol)

Creates a pair of connected sockets, useful for inter-process communication. Returns true on success, false on failure.

Parameters:

  • socket1 - Variable to receive the first socket

  • socket2 - Variable to receive the second socket

  • domain - Address family (typically :PF_UNIX)

  • type - Socket type (e.g., :SOCK_STREAM)

  • protocol - Protocol number (usually 0)

Example:

var (parent, child) = (nil, nil)
Socket.socketpair(parent, child, :PF_UNIX, :SOCK_STREAM, 0) || die "socketpair failed: #{$!}"

# Now parent and child can communicate bidirectionally

HOSTNAME AND ADDRESS RESOLUTION

gethostbyname

Socket.gethostbyname(name)

Looks up a host by name and returns host information including name, aliases, address type, and addresses.

Parameters:

  • name - The hostname to look up

Returns an array containing: [hostname, aliases, addrtype, addresses...]

Example:

var info = Socket.gethostbyname('localhost')
say "Host: #{info[0]}"
say "Address type: #{info[2]}"

gethostbyaddr

Socket.gethostbyaddr(addr, addrtype)

Looks up a host by its address and returns host information.

Parameters:

  • addr - The packed binary address

  • addrtype - Address family (e.g., :AF_INET)

Returns an array containing: [hostname, aliases, addrtype, addresses...]

Example:

var addr = Socket.inet_aton('127.0.0.1')
var info = Socket.gethostbyaddr(addr, :AF_INET)
say "Hostname: #{info[0]}"

gethostent

Socket.gethostent()

Retrieves the next entry from the hosts database. Used for iterating through the hosts file.

Returns an array of host information, or nil when no more entries exist.

Example:

Socket.sethostent(1)
while (var ent = Socket.gethostent()) {
    say ent[0]  # Print hostname
}

sethostent

Socket.sethostent(stayopen)

Opens and rewinds the hosts database. If stayopen is true, the database connection stays open between calls.

Parameters:

  • stayopen - Boolean indicating whether to keep the database open

Example:

Socket.sethostent(1)
# ... iterate through hosts ...

getaddrinfo

Socket.getaddrinfo(host, service, hints)

Performs modern address resolution, supporting both IPv4 and IPv6. Returns a list of address structures.

This is the preferred method for address resolution in modern code, as it handles both IPv4 and IPv6 transparently.

Example:

var results = Socket.getaddrinfo('www.example.com', 'http')
results.each { |addr|
    say addr
}

getnameinfo

Socket.getnameinfo(sockaddr, flags)

Converts a socket address to a hostname and service name. This is the reverse operation of getaddrinfo.

Parameters:

  • sockaddr - Packed socket address

  • flags - Optional flags to control the conversion

Returns a pair [hostname, servicename].

Example:

var sockaddr = Socket.pack_sockaddr_in(80, Socket.inet_aton('127.0.0.1'))
var (host, service) = Socket.getnameinfo(sockaddr)
say "Host: #{host}, Service: #{service}"

NETWORK DATABASE QUERIES

getnetbyname

Socket.getnetbyname(name)

Looks up a network by name and returns network information.

Parameters:

  • name - The network name to look up

Returns an array containing: [net_name, aliases, addrtype, net_address]

Example:

var net_info = Socket.getnetbyname('loopback')

getnetbyaddr

Socket.getnetbyaddr(addr, addrtype)

Looks up a network by its address.

Parameters:

  • addr - The network address

  • addrtype - Address family

Returns an array of network information.

getnetent

Socket.getnetent()

Retrieves the next entry from the networks database.

Returns an array of network information, or nil when exhausted.

setnetent

Socket.setnetent(stayopen)

Opens and rewinds the networks database.

Parameters:

  • stayopen - Boolean indicating whether to keep the database open

PROTOCOL DATABASE QUERIES

getprotobyname

Socket.getprotobyname(name)

Looks up a protocol by name and returns protocol information.

Parameters:

  • name - Protocol name (e.g., 'tcp', 'udp', 'icmp')

Returns an array containing: [proto_name, aliases, proto_number]

Example:

var proto = Socket.getprotobyname('tcp')
say "TCP protocol number: #{proto[2]}"

getprotobynumber

Socket.getprotobynumber(num)

Looks up a protocol by its number.

Parameters:

  • num - Protocol number

Returns an array of protocol information.

Example:

var proto = Socket.getprotobynumber(6)  # 6 is TCP
say "Protocol name: #{proto[0]}"

getprotoent

Socket.getprotoent()

Retrieves the next entry from the protocols database.

Returns an array of protocol information, or nil when exhausted.

setprotoent

Socket.setprotoent(stayopen)

Opens and rewinds the protocols database.

Parameters:

  • stayopen - Boolean indicating whether to keep the database open

SERVICE DATABASE QUERIES

getservbyname

Socket.getservbyname(name, proto)

Looks up a service by name and protocol.

Parameters:

  • name - Service name (e.g., 'http', 'ftp', 'ssh')

  • proto - Protocol name ('tcp' or 'udp')

Returns an array containing: [service_name, aliases, port, proto]

Example:

var service = Socket.getservbyname('http', 'tcp')
say "HTTP port: #{service[2]}"  # Should be 80

getservbyport

Socket.getservbyport(port, proto)

Looks up a service by port number and protocol.

Parameters:

  • port - Port number

  • proto - Protocol name ('tcp' or 'udp')

Returns an array of service information.

Example:

var service = Socket.getservbyport(22, 'tcp')
say "Port 22 service: #{service[0]}"  # Should be 'ssh'

getservent

Socket.getservent()

Retrieves the next entry from the services database.

Returns an array of service information, or nil when exhausted.

setservent

Socket.setservent(stayopen)

Opens and rewinds the services database.

Parameters:

  • stayopen - Boolean indicating whether to keep the database open

ADDRESS CONVERSION FUNCTIONS

inet_aton

Socket.inet_aton(hostname)

Converts an IPv4 address from dotted-quad string format to packed binary format.

Parameters:

  • hostname - IPv4 address as a string (e.g., '192.168.1.1')

Returns the packed binary address, or nil on error.

Example:

var addr = Socket.inet_aton('127.0.0.1')
# addr is now in binary format

inet_ntoa

Socket.inet_ntoa(addr)

Converts an IPv4 address from packed binary format to dotted-quad string format. This is the reverse of inet_aton.

Parameters:

  • addr - Packed binary address

Returns the address as a string.

Example:

var addr = Socket.inet_aton('192.168.1.1')
var str = Socket.inet_ntoa(addr)
say str  # Prints: 192.168.1.1

inet_pton

Socket.inet_pton(af, hostname)

Converts an IPv4 or IPv6 address from presentation (string) format to network (binary) format. This is the modern, protocol-agnostic version of inet_aton.

Parameters:

  • af - Address family (:AF_INET for IPv4, :AF_INET6 for IPv6)

  • hostname - IP address as a string

Returns the packed binary address.

Example:

var ipv4 = Socket.inet_pton(:AF_INET, '192.168.1.1')
var ipv6 = Socket.inet_pton(:AF_INET6, '::1')

inet_ntop

Socket.inet_ntop(af, addr)

Converts an IPv4 or IPv6 address from network (binary) format to presentation (string) format. This is the reverse of inet_pton.

Parameters:

  • af - Address family (:AF_INET or :AF_INET6)

  • addr - Packed binary address

Returns the address as a string.

Example:

var addr = Socket.inet_pton(:AF_INET6, '::1')
var str = Socket.inet_ntop(:AF_INET6, addr)
say str  # Prints: ::1

SOCKET ADDRESS PACKING/UNPACKING

pack_sockaddr_in

Socket.pack_sockaddr_in(port, ip_addr)

Packs a port number and IPv4 address into a binary sockaddr_in structure.

Parameters:

  • port - Port number (0-65535)

  • ip_addr - Packed IPv4 address (from inet_aton)

Returns a packed sockaddr_in structure.

Example:

var addr = Socket.inet_aton('127.0.0.1')
var sockaddr = Socket.pack_sockaddr_in(8080, addr)
# Can now be used with connect, bind, etc.

unpack_sockaddr_in

Socket.unpack_sockaddr_in(sockaddr)

Unpacks a sockaddr_in structure into port and address.

Parameters:

  • sockaddr - Packed sockaddr_in structure

Returns an array [port, ip_addr].

Example:

var sockaddr = Socket.pack_sockaddr_in(8080, Socket.inet_aton('127.0.0.1'))
var (port, addr) = Socket.unpack_sockaddr_in(sockaddr)
say "Port: #{port}"
say "IP: #{Socket.inet_ntoa(addr)}"

pack_sockaddr_in6

Socket.pack_sockaddr_in6(port, ip6_addr, scope_id, flowinfo)

Packs a port number and IPv6 address into a binary sockaddr_in6 structure.

Parameters:

  • port - Port number

  • ip6_addr - Packed IPv6 address (from inet_pton)

  • scope_id - Scope ID (optional, usually 0)

  • flowinfo - Flow info (optional, usually 0)

Returns a packed sockaddr_in6 structure.

Example:

var addr = Socket.inet_pton(:AF_INET6, '::1')
var sockaddr = Socket.pack_sockaddr_in6(8080, addr)

unpack_sockaddr_in6

Socket.unpack_sockaddr_in6(sockaddr)

Unpacks a sockaddr_in6 structure into its components.

Parameters:

  • sockaddr - Packed sockaddr_in6 structure

Returns an array [port, ip6_addr, scope_id, flowinfo].

Example:

var (port, addr, scope, flow) = Socket.unpack_sockaddr_in6(sockaddr)
say "Port: #{port}"
say "IPv6: #{Socket.inet_ntop(:AF_INET6, addr)}"

pack_sockaddr_un

Socket.pack_sockaddr_un(path)

Packs a filesystem path into a Unix domain socket address structure.

Parameters:

  • path - Filesystem path for the Unix socket

Returns a packed sockaddr_un structure.

Example:

var sockaddr = Socket.pack_sockaddr_un('/tmp/my.sock')

unpack_sockaddr_un

Socket.unpack_sockaddr_un(sockaddr)

Unpacks a Unix domain socket address structure.

Parameters:

  • sockaddr - Packed sockaddr_un structure

Returns the filesystem path.

Example:

var path = Socket.unpack_sockaddr_un(sockaddr)
say "Socket path: #{path}"

sockaddr_family

Socket.sockaddr_family(sockaddr)

Extracts the address family from a packed socket address.

Parameters:

  • sockaddr - Packed socket address structure

Returns the address family constant (e.g., :AF_INET, :AF_INET6).

Example:

var family = Socket.sockaddr_family(sockaddr)
if (family == :AF_INET) {
    say "IPv4 address"
}

sockaddr_in

Socket.sockaddr_in(sockaddr)

Convenience method combining unpack_sockaddr_in and inet_ntoa to extract human-readable information from an IPv4 socket address.

Parameters:

  • sockaddr - Packed sockaddr_in structure

Returns [port, ip_string].

Example:

var (port, ip) = Socket.sockaddr_in(sockaddr)
say "Connecting to #{ip}:#{port}"

sockaddr_in6

Socket.sockaddr_in6(sockaddr)

Convenience method for extracting human-readable information from an IPv6 socket address.

Parameters:

  • sockaddr - Packed sockaddr_in6 structure

Returns [port, ip6_string, scope_id, flowinfo].

sockaddr_un

Socket.sockaddr_un(sockaddr)

Convenience method that unpacks a Unix domain socket address.

Parameters:

  • sockaddr - Packed sockaddr_un structure

Returns the filesystem path.

MULTICAST GROUP MEMBERSHIP

pack_ip_mreq

Socket.pack_ip_mreq(multiaddr, interface)

Packs a multicast group membership request for IPv4.

Parameters:

  • multiaddr - Multicast group address (packed)

  • interface - Local interface address (packed)

Returns a packed ip_mreq structure for use with setsockopt.

Example:

var mcast_addr = Socket.inet_aton('239.255.0.1')
var iface_addr = Socket.inet_aton('0.0.0.0')
var mreq = Socket.pack_ip_mreq(mcast_addr, iface_addr)

unpack_ip_mreq

Socket.unpack_ip_mreq(mreq)

Unpacks an ip_mreq structure.

Parameters:

  • mreq - Packed ip_mreq structure

Returns [multiaddr, interface].

pack_ip_mreq_source

Socket.pack_ip_mreq_source(multiaddr, source, interface)

Packs a source-specific multicast group membership request for IPv4.

Parameters:

  • multiaddr - Multicast group address

  • source - Source address to receive from

  • interface - Local interface address

Returns a packed ip_mreq_source structure.

unpack_ip_mreq_source

Socket.unpack_ip_mreq_source(mreq_source)

Unpacks an ip_mreq_source structure.

Parameters:

  • mreq_source - Packed ip_mreq_source structure

Returns [multiaddr, source, interface].

pack_ipv6_mreq

Socket.pack_ipv6_mreq(multiaddr, interface_index)

Packs a multicast group membership request for IPv6.

Parameters:

  • multiaddr - IPv6 multicast group address (packed)

  • interface_index - Interface index number

Returns a packed ipv6_mreq structure.

Example:

var mcast_addr = Socket.inet_pton(:AF_INET6, 'ff02::1')
var mreq = Socket.pack_ipv6_mreq(mcast_addr, 0)

unpack_ipv6_mreq

Socket.unpack_ipv6_mreq(mreq)

Unpacks an ipv6_mreq structure.

Parameters:

  • mreq - Packed ipv6_mreq structure

Returns [multiaddr, interface_index].

EXAMPLES

Simple TCP Client

var sock = Socket()
sock.open(:PF_INET, :SOCK_STREAM, 0) || die "Cannot create socket: #{$!}"

var addr = Socket.inet_aton('127.0.0.1')
var sockaddr = Socket.pack_sockaddr_in(80, addr)

sock.connect(sockaddr) || die "Cannot connect: #{$!}"
sock.print("GET / HTTP/1.0\r\n\r\n")

while (var line = sock.readline) {
    say line
}
sock.close()

UDP Socket

var sock = Socket()
sock.open(:PF_INET, :SOCK_DGRAM, 0) || die "Cannot create socket: #{$!}"

var dest = Socket.pack_sockaddr_in(9999, Socket.inet_aton('192.168.1.100'))
sock.send("Hello UDP", 0, dest)

Unix Domain Socket

var sock = Socket()
sock.open(:PF_UNIX, :SOCK_STREAM, 0) || die "Cannot create socket: #{$!}"

var addr = Socket.pack_sockaddr_un('/tmp/my.sock')
sock.connect(addr) || die "Cannot connect: #{$!}"

IPv6 Socket

var sock = Socket()
sock.open(:PF_INET6, :SOCK_STREAM, 0) || die "Cannot create socket: #{$!}"

var addr = Socket.inet_pton(:AF_INET6, '::1')
var sockaddr = Socket.pack_sockaddr_in6(8080, addr)
sock.connect(sockaddr) || die "Cannot connect: #{$!}"

SEE ALSO

  • Sidef::Types::Glob::File - File I/O operations

  • Socket - Perl Socket module documentation

  • socket(2) - Unix socket system call

  • connect(2), bind(2), listen(2), accept(2) - Socket operations

AUTHOR

Daniel Șuteu (trizen)