NAME
Sidef::Types::Glob::Socket - Socket networking interface for Sidef
DESCRIPTION
The Socket class provides an interface to socket networking operations in Sidef. A Socket object itself is a lightweight, stateless helper: it is used to create sockets (via "open" or "socketpair") and to reach the full set of constants and address-conversion helpers exported by Perl's core Socket module — it does not itself represent an open connection.
Once you have an actual connection, you work with it through a Sidef::Types::Glob::SocketHandle object (returned by "open", "socketpair", or SocketHandle's own accept) — that's where bind, listen, accept, connect, send, recv, and the inherited file-handle methods (read, print, say, close, ...) live.
Constants and conversion helpers: Every name exported by Perl's core Socket module (address family constants like AF_INET, socket type constants like SOCK_STREAM, option constants like SO_REUSEADDR, and helper functions such as inet_aton or pack_sockaddr_in) is automatically made available as a method on Socket — called with no arguments for a constant, or with the appropriate arguments for a function. Arguments you pass in are unwrapped to plain values before being handed to the underlying Perl function, and results are wrapped back into the corresponding Sidef type. This means Socket.AF_INET, Socket.SOCK_STREAM, Socket.SO_REUSEADDR, and so on are all available even though they aren't individually listed below — this documentation covers the ones you're most likely to need directly.
SYNOPSIS
# Create and open a TCP socket
var sock = Socket.open(Socket.PF_INET, Socket.SOCK_STREAM, 0) || die "Cannot open socket: #{$!}"
# Resolve a hostname to its packed address
var addr = Socket.inet_aton('127.0.0.1')
# Pack a socket address
var sockaddr = Socket.pack_sockaddr_in(80, addr)
sock.connect(sockaddr) || die "Cannot connect: #{$!}"
# Create a socket pair for IPC
Socket.socketpair(\var reader, \var writer, Socket.PF_UNIX, Socket.SOCK_STREAM, 0)
INHERITS
Inherits methods from Sidef::Object::Object.
CONSTRUCTION
new
Socket.new
Creates a new, empty Socket helper object. This does not open any actual socket by itself — it takes no arguments, and any given are ignored. Use "open" on the resulting object to actually create a socket.
CREATING SOCKETS
open
self.open(domain, type, protocol)
Creates a new socket with the given domain (address family), type, and protocol, and returns it as a Sidef::Types::Glob::SocketHandle — not a boolean. Returns nil on failure. domain, type, and protocol should be plain numeric values, typically obtained from the constant methods below (e.g. Socket.PF_INET, Socket.SOCK_STREAM).
var sock = Socket.open(Socket.PF_INET, Socket.SOCK_STREAM, 0)
sock || die "Cannot open socket: #{$!}"
var udp = Socket.open(Socket.PF_INET, Socket.SOCK_DGRAM, 0)
socketpair
self.socketpair(var1, var2, domain, type, protocol)
Creates a pair of connected, unnamed sockets (typically for local inter-process communication) and assigns the two resulting Sidef::Types::Glob::SocketHandle objects into var1 and var2, which must be passed by reference. Returns a boolean indicating success.
Socket.socketpair(\var parent, \var child, Socket.PF_UNIX, Socket.SOCK_STREAM, 0) \
|| die "socketpair failed: #{$!}"
parent.say("hello from parent")
say child.readline
HOST, NETWORK, PROTOCOL, AND SERVICE LOOKUPS
These methods query the traditional Unix host/network/protocol/service databases. Unlike the array-returning lookups you may have seen elsewhere in Sidef, each of these calls the underlying Perl function in a way that yields a single value rather than a full record — see each method for exactly what that value is.
gethostbyname
self.gethostbyname(name)
Resolves a hostname and returns its packed binary network address (not a hostname, and not a record). Returns nil if the name can't be resolved.
var addr = Socket.gethostbyname('localhost')
say Socket.inet_ntoa(addr) # e.g. "127.0.0.1"
gethostbyaddr
self.gethostbyaddr(addr, addrtype)
Resolves a packed binary address back to a hostname string. addrtype is an address family, typically Socket.AF_INET. Returns nil if the address can't be resolved.
var addr = Socket.inet_aton('127.0.0.1')
var name = Socket.gethostbyaddr(addr, Socket.AF_INET)
say name # e.g. "localhost"
gethostent
self.gethostent
Returns the name of the next entry from the hosts database, or nil when there are no more entries. Use "sethostent" to rewind.
Socket.sethostent(1)
while (defined(var name = Socket.gethostent)) {
say name
}
sethostent
self.sethostent(stayopen)
Opens and rewinds the hosts database. If stayopen is true, the database connection is kept open between calls. Returns a boolean.
getnetbyname
self.getnetbyname(name)
Looks up a network by name and returns its address as a single value. Returns nil if not found.
var net = Socket.getnetbyname('loopback')
getnetbyaddr
self.getnetbyaddr(addr, addrtype)
Looks up a network by address and returns its name. Returns nil if not found.
getnetent
self.getnetent
Returns the next entry's name from the networks database, or nil when exhausted. Use "setnetent" to rewind.
setnetent
self.setnetent(stayopen)
Opens and rewinds the networks database. If stayopen is true, the connection is kept open between calls. Returns a boolean.
getprotobyname
self.getprotobyname(name)
Looks up a protocol by name (e.g. 'tcp') and returns its protocol number. Returns nil if not found.
say Socket.getprotobyname('tcp') # 6
getprotobynumber
self.getprotobynumber(num)
Looks up a protocol by number and returns its name. Returns nil if not found.
say Socket.getprotobynumber(6) # "tcp"
getprotoent
self.getprotoent
Returns the next entry's protocol number from the protocols database, or nil when exhausted. Use "setprotoent" to rewind.
setprotoent
self.setprotoent(stayopen)
Opens and rewinds the protocols database. If stayopen is true, the connection is kept open between calls. Returns a boolean.
getservbyname
self.getservbyname(name, proto)
Looks up a service by name and protocol (e.g. 'tcp' or 'udp') and returns its port number (as a string). Returns nil if not found.
say Socket.getservbyname('http', 'tcp') # "80"
getservbyport
self.getservbyport(port, proto)
Looks up a service by port number and protocol, returning its name. Returns nil if not found.
say Socket.getservbyport(22, 'tcp') # "ssh"
getservent
self.getservent
Returns the next entry's service name from the services database, or nil when exhausted. Use "setservent" to rewind.
setservent
self.setservent(stayopen)
Opens and rewinds the services database. If stayopen is true, the connection is kept open between calls. Returns a boolean.
MODERN ADDRESS RESOLUTION
getaddrinfo
self.getaddrinfo(host, service)
self.getaddrinfo(host, service, hints)
Performs modern, protocol-agnostic address resolution (supporting both IPv4 and IPv6). The returned array's first element is an error message (empty on success), followed by one entry per resolved address.
var res = Socket.getaddrinfo('www.example.com', 'http')
var err = res[0]
if (err == '') {
res.slice(1).each { |entry|
say entry
}
}
else {
say "getaddrinfo failed: #{err}"
}
getnameinfo
self.getnameinfo(sockaddr)
self.getnameinfo(sockaddr, flags)
Converts a socket address into a hostname and service name (the reverse of "getaddrinfo"). Returns a three-element array: an error message (empty on success), the hostname, and the service name.
var sockaddr = Socket.pack_sockaddr_in(80, Socket.inet_aton('127.0.0.1'))
var res = Socket.getnameinfo(sockaddr)
if (res[0] == '') {
say "Host: #{res[1]}, Service: #{res[2]}"
}
ADDRESS CONVERSION
inet_aton
self.inet_aton(address)
Converts an IPv4 address from dotted-quad string format to packed binary format. Returns nil on error.
var addr = Socket.inet_aton('127.0.0.1')
inet_ntoa
self.inet_ntoa(addr)
Converts a packed binary IPv4 address to dotted-quad string format — the reverse of "inet_aton".
say Socket.inet_ntoa(Socket.inet_aton('192.168.1.1')) # "192.168.1.1"
inet_pton
self.inet_pton(af, address)
Converts an IPv4 or IPv6 address from string form to packed binary form. af is Socket.AF_INET or Socket.AF_INET6. This is the protocol-agnostic successor to "inet_aton".
var ipv4 = Socket.inet_pton(Socket.AF_INET, '192.168.1.1')
var ipv6 = Socket.inet_pton(Socket.AF_INET6, '::1')
inet_ntop
self.inet_ntop(af, addr)
Converts a packed binary address to string form — the reverse of "inet_pton".
var addr = Socket.inet_pton(Socket.AF_INET6, '::1')
say Socket.inet_ntop(Socket.AF_INET6, addr) # "::1"
SOCKET ADDRESS PACKING/UNPACKING
pack_sockaddr_in
self.pack_sockaddr_in(port, ip_addr)
Packs a port number and IPv4 address (from "inet_aton") into a binary sockaddr_in structure, suitable for "bind" in SocketHandle or "connect" in SocketHandle.
var sockaddr = Socket.pack_sockaddr_in(8080, Socket.inet_aton('127.0.0.1'))
unpack_sockaddr_in
self.unpack_sockaddr_in(sockaddr)
Unpacks a sockaddr_in structure, returning a [port, ip_addr] array.
var sockaddr = Socket.pack_sockaddr_in(8080, Socket.inet_aton('127.0.0.1'))
var res = Socket.unpack_sockaddr_in(sockaddr)
say "Port: #{res[0]}, IP: #{Socket.inet_ntoa(res[1])}"
pack_sockaddr_in6
self.pack_sockaddr_in6(port, ip6_addr, scope_id=0, flowinfo=0)
Packs a port number and IPv6 address (from "inet_pton") into a binary sockaddr_in6 structure.
var addr = Socket.inet_pton(Socket.AF_INET6, '::1')
var sockaddr = Socket.pack_sockaddr_in6(8080, addr)
unpack_sockaddr_in6
self.unpack_sockaddr_in6(sockaddr)
Unpacks a sockaddr_in6 structure, returning [port, ip6_addr, scope_id, flowinfo].
pack_sockaddr_un
self.pack_sockaddr_un(path)
Packs a filesystem path into a Unix domain socket address structure.
var sockaddr = Socket.pack_sockaddr_un('/tmp/my.sock')
unpack_sockaddr_un
self.unpack_sockaddr_un(sockaddr)
Unpacks a Unix domain socket address structure, returning the filesystem path.
sockaddr_family
self.sockaddr_family(sockaddr)
Extracts the address family from any packed socket address structure.
var family = Socket.sockaddr_family(sockaddr)
if ((family == Socket.AF_INET)) {
say "IPv4 address"
}
MULTICAST GROUP MEMBERSHIP
pack_ip_mreq
self.pack_ip_mreq(multiaddr, interface)
Packs an IPv4 multicast group membership request, for use with "setsockopt" in SocketHandle.
var mreq = Socket.pack_ip_mreq(Socket.inet_aton('239.255.0.1'), Socket.inet_aton('0.0.0.0'))
unpack_ip_mreq
self.unpack_ip_mreq(mreq)
Unpacks an ip_mreq structure, returning [multiaddr, interface].
pack_ip_mreq_source
self.pack_ip_mreq_source(multiaddr, source, interface)
Packs a source-specific IPv4 multicast group membership request.
unpack_ip_mreq_source
self.unpack_ip_mreq_source(mreq_source)
Unpacks an ip_mreq_source structure, returning [multiaddr, source, interface].
pack_ipv6_mreq
self.pack_ipv6_mreq(multiaddr, interface_index)
Packs an IPv6 multicast group membership request.
var mreq = Socket.pack_ipv6_mreq(Socket.inet_pton(Socket.AF_INET6, 'ff02::1'), 0)
unpack_ipv6_mreq
self.unpack_ipv6_mreq(mreq)
Unpacks an ipv6_mreq structure, returning [multiaddr, interface_index].
EXAMPLES
Simple TCP Client
var sock = Socket.open(Socket.PF_INET, Socket.SOCK_STREAM, 0) || die "Cannot create socket: #{$!}"
var sockaddr = Socket.pack_sockaddr_in(80, Socket.inet_aton('127.0.0.1'))
sock.connect(sockaddr) || die "Cannot connect: #{$!}"
sock.print("GET / HTTP/1.0\r\n\r\n")
while (defined(var line = sock.readline)) {
say line
}
sock.close
UDP Socket
var sock = Socket.open(Socket.PF_INET, Socket.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.open(Socket.PF_UNIX, Socket.SOCK_STREAM, 0) || die "Cannot create socket: #{$!}"
var sockaddr = Socket.pack_sockaddr_un('/tmp/my.sock')
sock.connect(sockaddr) || die "Cannot connect: #{$!}"
IPv6 Socket
var sock = Socket.open(Socket.PF_INET6, Socket.SOCK_STREAM, 0) || die "Cannot create socket: #{$!}"
var addr = Socket.inet_pton(Socket.AF_INET6, '::1')
var sockaddr = Socket.pack_sockaddr_in6(8080, addr)
sock.connect(sockaddr) || die "Cannot connect: #{$!}"
SEE ALSO
Sidef::Types::Glob::SocketHandle - The open connection object returned by "open"
Sidef::Types::Glob::FileHandle - File I/O operations, inherited by SocketHandle
Socket - Perl's Socket module, which this class delegates to
socket(2), connect(2), bind(2), listen(2), accept(2) - Underlying Unix socket system calls