Socket¶
Usage
use Socket;
or
import Socket;
Supports inter-process communication through IP sockets.
The Socket module focuses on connecting, accepting sockets and providing interface for communication between them. Also provided are some constant values representing common idioms in socket programming, such as standard Addresses, Families and Flags.
To those familiar with the Unix socket API, the method names will feel familiar, though their usage will be somewhat simpler than the raw Unix socket API.
Records¶
Procedures¶
bind
connect
getPeerName
getSockOpt
getSockName
listen
setSockOpt
Records, Types and Function Definitions¶
- enum IPFamily { IPv4 = 2, IPv6 = 10, IPUnspec = 0 }¶
Available values for different Internet Protocol Families to be used when creating Sockets.
- enum constant IPv4 = 2¶
IPv4
- enum constant IPv6 = 10¶
IPv6
- enum constant IPUnspec = 0¶
IP Unspecified
- type ipv4Addr = sys_in_addr_t¶
Type of Standard IPv4 Address
- const IPv4Any: ipv4Addr = INADDR_ANY¶
- const IPv4Broadcast: ipv4Addr = INADDR_BROADCAST¶
- type ipv6Addr = sys_in6_addr_t¶
Type of Standard IPv6 Address
- const IPv6Any: ipv6Addr = in6addr_any¶
- record ipAddr: writeSerializable¶
Abstract supertype for network addresses. Contains data about
IPFamily
, host and port. It supports both IPv4 and IPv6 addresses. ipAddr can be compared using == and != operators.- proc host¶
Returns the host address. :return: host address :rtype: string
- proc port¶
Returns the port stored in record. :return: Returns numeric port. :rtype: uint(16)
- operator =(in other: ipAddr)¶
- proc type ipAddr.create(host: string = "127.0.0.1", port: uint(16) = 8000, family: IPFamily = IPFamily.IPv4): ipAddr throws¶
Returns a new record of type
ipAddr
provided host, port and family. this function is equivalent to the following code:- Arguments
host : string – address string in dot-dash or colon notation depending on family.
port : uint(16) – network address’s port.
family :
IPFamily
– value of IP Family
- Returns
address instance.
- Return type
ipAddr
- Throws
SystemError – Upon incompatible host, port or family
- proc type ipAddr.ipv4(host: ipv4Addr, port: uint(16) = 8000): ipAddr throws¶
Returns a new record of type ipAddr provided host and port. The family type is assumed based on host which is a standard address. this function is equivalent to the following code:
- Arguments
host : ipv4Addr – standard ipv4 address.
port : uint(16) – network address’s port.
- Returns
address instance.
- Return type
ipAddr
- Throws
SystemError – Upon incompatible host, port or family
- proc type ipAddr.ipv6(host: ipv6Addr, port: uint(16) = 8000): ipAddr throws¶
Returns a new record of type ipAddr provided host and port. The family type is assumed based on host which is a standard address. this function is equivalent to the following code:
- Arguments
host : ipv6Addr – standard ipv6 address.
port : uint(16) – network address’s port.
- Returns
address instance.
- Return type
ipAddr
- Throws
SystemError – Upon incompatible host, port or family
- const indefiniteTimeout: struct_timeval¶
Get a
struct_timeval
set for indefinite timeout.This is the default value used in various procedures in this module
tv_sec is assigned a value of
-1
tv_usec is assigned a value of
0
- proc tcpConn.socketFd throws¶
Returns the file descriptor associated with socket :return: file descriptor :rtype: int(32)
- proc tcpConn.addr throws¶
Returns the address of remote socket connection :return: Returns remote address :rtype: ipAddr
- proc ref tcpConn.setNagle(enable: bool) throws¶
Enables or disables Nagle’s algorithm on a given TCP Connection.
- Arguments
enable : bool – whether to enable or disable Nagle’s algorithm
- Throws
SystemError – if not able to set TCP_NODELAY flag properly
- proc tcpConn.setDelayAck(enable: bool) throws¶
Enables or disables Delayed Ack optimization on a given TCP Connection.
- Arguments
enable : bool – whether to enable or disable Nagle’s algorithm
- Throws
SystemError – if not able to set TCP_QUICKACK flag properly
- type sys_in_addr_t¶
- type sys_in6_addr_t¶
- const INADDR_ANY: sys_in_addr_t¶
- const INADDR_BROADCAST: sys_in_addr_t¶
- const INADDR_LOOPBACK: sys_in_addr_t¶
- const in6addr_any: sys_in6_addr_t¶
- const in6addr_loopback: sys_in6_addr_t¶
- const AF_INET: c_int¶
- const AF_INET6: c_int¶
- record tcpListener: writeSerializable¶
A record holding reference to a tcp socket bound and listening for connections.
- var socketFd: int(32) = -1¶
File Descriptor Associated with instance
- proc deinit()¶
- proc tcpListener.accept(in timeout: struct_timeval = indefiniteTimeout): tcpConn throws¶
Waits for a new connection based on timeout and returns a new
tcpConn
if successful. Default time to wait for a new connection is indefinite.const server = listen(ipAddr.create()); const client = server.accept()
- Arguments
timeout :
struct_timeval
– time to wait for new connection.- Returns
accepted connection
- Return type
tcpConn
- Throws
Error – Upon timeout completion without any new connection
- proc tcpListener.accept(timeout: real): tcpConn throws
- proc ref tcpListener.close() throws¶
Close the file descriptor
- proc tcpListener.addr throws¶
Returns the address on which socket is listening on and bound to.
- Returns
bound address
- Return type
ipAddr
- proc ref tcpListener.setNagle(enable: bool) throws¶
Enables or disables Nagle’s algorithm on a given TCP Listener.
- Arguments
enable : bool – whether to enable or disable Nagle’s algorithm
- Throws
SystemError – if not able to set TCP_NODELAY option properly
- proc ref tcpListener.setDelayAck(enable: bool) throws¶
Enables or disables Delayed Ack optimization on a given TCP Listener.
- Arguments
enable : bool – whether to enable or disable Nagle’s algorithm
- Throws
SystemError – if not able to set TCP_QUICKACK flag properly
- const backlogDefault: uint(16) = if SOMAXCONN <= 128 then SOMAXCONN else 128: uint(16)¶
Default backlog value used in
listen
It is calculated as min(SOMAXCONN, 128) where SOMAXCONN is the maximum number of allowed pending connections in the system.
- proc listen(in address: ipAddr, reuseAddr: bool = true, backlog: uint(16) = backlogDefault): tcpListener throws¶
Convenience procedure which creates a new
tcpListener
bound to and listening on address for new connections. backlog determines how many connections can be pending (not having called accept) before the socket will begin to reject them. The default value of backlog is backlogDefault.const address = ipAddr.create("127.0.0.1", 8000, IPFamily.IPv4); const server = listen(address);
- Arguments
address :
ipAddr
– address to connect toreuseAddr : bool – whether to reuse address if already in use
backlog : uint(16) – maximum number of pending connections
- Returns
connected socket
- Return type
tcpListener
- Throws
SystemError – On failure to bind or listen on address
- proc connect(const ref address: ipAddr, in timeout = indefiniteTimeout): tcpConn throws¶
Convenience procedure which creates a
tcpConn
connected to address.`timeout` determines how much time to wait for connection to be established. The default value for timeout is indefinite.import OS.POSIX.struct_timeval; const address = ipAddr.create("127.0.0.1", 8000, IPFamily.IPv4); const timeout = new struct_timeval(4,0); const connectedClient = connect(address, timeout);
- Arguments
address :
ipAddr
– address to connect totimeout :
struct_timeval
– time to wait for connection establishment.
- Returns
connected socket
- Return type
tcpConn
- Throws
SystemError – Upon failure to connect
- proc connect(const ref address: ipAddr, in timeout: real): tcpConn throws
- proc connect(in host: string, in service: string, family: IPFamily = IPFamily.IPUnspec, in timeout = indefiniteTimeout): tcpConn throws
This overload of connect not only returns a
tcpConn
but also does DNS resolution for the provided host. The timeout is tried for all resolved addresses and the first successful one is returned back.import OS.POSIX.struct_timeval; const timeout = new struct_timeval(4,0); const connectedClient = connect("google.com", "http", IPFamily.IPv4, timeout);
- Arguments
host : string – host to connect to or resolve if not in standard ip notation
service : string – service to connect to on resolved host
family :
IPFamily
– type of socket family to connect totimeout :
struct_timeval
– time to wait for each possible connection.
- Returns
connected socket
- Return type
tcpConn
- Throws
SystemError – Upon failure to resolve address or connect to any of the resolved address in given timeout.
- proc connect(in host: string, in service: string, family: IPFamily = IPFamily.IPUnspec, timeout: real): tcpConn throws
- proc connect(in host: string, in port: uint(16), family: IPFamily = IPFamily.IPUnspec, timeout = indefiniteTimeout): tcpConn throws
This overload of connect not only returns a
tcpConn
but also does DNS resolution for the provided host. The timeout is tired for all resolved addresses and the first successful one is returned back.import OS.POSIX.struct_timeval; const timeout = new struct_timeval(4,0); const connectedClient = connect("google.com", 80, IPFamily.IPv4, timeout);
- Arguments
host : string – address of host to connect or resolve if not in ip notation
port : uint(16) – port to connect to on host
family :
IPFamily
– type of socket family to connect totimeout :
struct_timeval
– time to wait for each possible connection.
- Returns
connected socket
- Return type
tcpConn
- Throws
SystemError – Upon failure to resolve address or connect to any of the resolved address in given timeout.
- proc connect(in host: string, in port: uint(16), family: IPFamily = IPFamily.IPUnspec, timeout: real): tcpConn throws
- record udpSocket: writeSerializable¶
A record holding reference to a udp socket bound to any available port.
- var socketFd: int(32)¶
File Descriptor Associated with instance
- proc init(family: IPFamily = IPFamily.IPv4)¶
Create a UDP socket of provided Family.
- proc deinit()¶
- proc udpSocket.close throws¶
- proc udpSocket.recvfrom(bufferLen: int, in timeout = indefiniteTimeout, flags: c_int = 0): (bytes, ipAddr) throws¶
Reads upto bufferLen bytes from the socket, and return a tuple of (data, address), where address will be a
ipAddr
pointing to address of the socket from where data was received.import OS.POSIX.struct_timeval; const timeout = new struct_timeval(4,0); const socket = new udpSocket(); const (data, sender) = socket.recvFrom(40, timeout);
- Arguments
bufferLen : int – number of bytes to read
timeout :
struct_timeval
– time to wait for data to arrive.
- Returns
tuple of (data, address)
- Return type
- Throws
SystemError – Upon failure to receive any data within given timeout.
- proc udpSocket.recvfrom(bufferLen: int, timeout: real, flags: c_int = 0): (bytes, ipAddr) throws
- proc udpSocket.recv(bufferLen: int, in timeout = indefiniteTimeout) throws¶
Reads incoming bufferLen number of bytes on socket, and return a tuple of read bytes, which can have size smaller than asked and if the size is more they will be truncated.
import OS.POSIX.struct_timeval; const timeout = new struct_timeval(4,0); const socket = new udpSocket(); const data = socket.recv(40, timeout);
- Arguments
bufferLen : int – number of bytes to read
timeout :
struct_timeval
– time to wait for data to arrive.
- Returns
data
- Return type
- Throws
SystemError – Upon failure to receive any data within given timeout.
- proc udpSocket.recv(bufferLen: int, timeout: real) throws
- proc udpSocket.send(data: bytes, in address: ipAddr, in timeout = indefiniteTimeout): c_ssize_t throws¶
Send data over socket to the provided address and return number of bytes sent if successful.
import OS.POSIX.struct_timeval; const timeout = new struct_timeval(4,0); const socket = new udpSocket(); const sentBytes = socket.send("hello world!":bytes, timeout);
- Arguments
data :
bytes
– data to send to addressaddress :
ipAddr
– socket address for sending datatimeout :
struct_timeval
– time to wait for data to arrive.
- Returns
sentBytes
- Return type
c_ssize_t
- Throws
SystemError – Upon failure to send any data within given timeout.
- proc udpSocket.send(data: bytes, in address: ipAddr, timeout: real) throws
- const SO_ACCEPTCONN: c_int¶
- const SO_BROADCAST: c_int¶
- const SO_DEBUG: c_int¶
- const SO_ERROR: c_int¶
- const SO_KEEPALIVE: c_int¶
- const SO_LINGER: c_int¶
- const SO_OOBINLINE: c_int¶
- const SO_RCVBUF: c_int¶
- const SO_RCVTIMEO: c_int¶
- const SO_REUSEADDR: c_int¶
- const SO_SNDBUF: c_int¶
- const SO_SNDTIMEO: c_int¶
- const SO_SECINFO: c_int¶
- proc setSockOpt(ref socket: ?t, level: c_int, optname: c_int, value: c_int) throws where t == udpSocket || t == tcpConn || t == tcpListener¶
Set the value of the given socket option (see setsockopt(2)) on provided
tcpConn
. The needed symbolic constants (SO_* etc.) are defined above.setSockOpt(socket, IPPROTO_TCP, TCP_QUICKACK, 1:c_int);
- Arguments
socket : tcpConn or udpSocket or tcpListener – socket to set option on
level : int(32) – protocol level
optname : int(32) – option to set.
value : int(32) – value to set on option
- Throws
SystemError – Upon incompatible arguments and socket.
- proc setSockOpt(ref socket: ?t, level: c_int, optname: c_int, value: bytes) throws where t == udpSocket || t == tcpConn || t == tcpListener
Overload for
setSockOpt
that allows setting abytes
value on socket option. This is useful for setsockopt calls that work with a C struct, including SO_LINGER, SO_RCVTIMEO, and SO_SNDTIMEO. It is up to the caller to ensure that the value which is abytes
parameter contains the proper bits.- Arguments
socket : tcpConn or tcpListener or udpSocket – socket to set option on
level : int(32) – protocol level
optname : int(32) – option to set.
value :
bytes
– value to set on option
- Throws
SystemError – Upon incompatible arguments and socket.
- proc setSockOpt(ref socket: ?t, level: c_int, optname: c_int, value: nothing, optlen: socklen_t) throws where t == udpSocket || t == tcpConn || t == tcpListener
Overload for
setSockOpt
which is equivalent to calling setsockopt() C function with optval=NULL and optlen=optlen.- Arguments
socket : tcpConn or tcpListener or udpSocket – socket to set option on
level : int(32) – protocol level
optname : int(32) – option to set.
value : nothing – None
optlen : int(32) – size of option
- Throws
SystemError – Upon incompatible arguments and socket.
- proc getSockOpt(ref socket: ?t, level: c_int, optname: c_int): int(32) throws where t == udpSocket || t == tcpConn || t == tcpListener¶
Returns the value of the given socket option (see getsockopt) on provided
tcpConn
. The needed symbolic constants (SO_* etc.) are defined above.- Arguments
socket : tcpConn or udpSocket or tcpListener – socket to set option on
level : int(32) – protocol level
optname : int(32) – option to set.
- Returns
value of socket option
- Return type
int(32)
- Throws
SystemError – Upon incompatible arguments and socket.
- proc getSockOpt(ref socket: ?t, level: c_int, optname: c_int, buflen: uint(16)): bytes throws where t == udpSocket || t == tcpConn || t == tcpListener
Returns the value of the given socket option which is expected to be of type
bytes
on providedtcpConn
.- Arguments
socket : tcpConn or udpSocket or tcpListener – socket to set option on
level : int(32) – protocol level
optname : int(32) – option to set.
- Returns
value of socket option
- Return type
- Throws
SystemError – Upon incompatible arguments and socket.
- proc getPeerName(ref socket: tcpConn): ipAddr throws¶
Returns the remote address to which socket is connected. This is useful to find out the address and port number of a remote IPv4/v6 socket, for instance.
- Arguments
socket : tcpConn – socket to set option on
- Returns
remote address
- Return type
ipAddr
- Throws
SystemError – If socket is not connected
- proc getSockName(ref socket: ?t): ipAddr throws where t == udpSocket || t == tcpConn || t == tcpListener¶
Returns the socket’s own address. This is useful to find out the port number of a IPv4/v6 socket, for instance.
- Arguments
socket : tcpConn or udpSocket or tcpListener – socket to set option on
- Returns
remote address
- Return type
ipAddr
- Throws
SystemError – If socket is closed
- proc bind(ref socket: ?t, ref address: ipAddr, reuseAddr = true) throws where t == udpSocket || t == tcpConn || t == tcpListener¶
Bind the socket to address. The socket must not already be bound to any address prior to calling this procedure.
var socket = new udpSocket(); var address = ipAddr.create("127.0.0.1", 8111); bind(socket, address);
- Arguments
socket : tcpConn or udpSocket or tcpListener – socket to set option on
address : boolean – address to bind to
reuseAddr – whether to reuse address if already in use
- Throws
SystemError – If socket is closed or already bound