Socket

Usage

use Socket;

or

import Socket;

Socket Module library, specifically related to 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. For more constants that can used alongside refer to Sys.

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.

Enum

IPFamily

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.

type ipv4Addr = sys_in_addr_t

Type of Standard IPv4 Address

const IPv4Localhost: ipv4Addr = INADDR_LOOPBACK

Standard IPv4 Addresses of type ipv4Addr

const IPv4Any: ipv4Addr = INADDR_ANY
const IPv4Broadcast: ipv4Addr = INADDR_BROADCAST
type ipv6Addr = sys_in6_addr_t

Type of Standard IPv6 Address

const IPv6Localhost: ipv6Addr = in6addr_loopback

Standard IPv6 Addresses of type ipv6Addr

const IPv6Any: ipv6Addr = in6addr_any
record ipAddr

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 family

Returns the family type of address. :return: family type of address :rtype: IPFamily

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)

proc type =(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

type tcpConn = file

The type returned from connect

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

record tcpListener

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: timeval = new timeval(-1, 0)): 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 – 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 to

  • timeout – standard ipv6 address.

Returns

connected socket

Return type

tcpConn

Throws

SystemError – On failure to bind or listen on address

proc connect(const ref address: ipAddr, in timeout = new timeval(-1, 0)): 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.

const address = ipAddr.create("127.0.0.1", 8000, IPFamily.IPv4);
const timeout = new timeval(4,0);
const connectedClient = connect(address, timeout);
Arguments
  • address : ipAddr – address to connect to

  • timeout – 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 = new timeval(-1, 0)): 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.

const timeout = new 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 to

  • timeout – 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 = new timeval(-1, 0)): 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.

const timeout = new 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 to

  • timeout – 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

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.addr throws

Get ipAddr associated with udp socket

proc udpSocket.close throws
proc udpSocket.recvfrom(bufferLen: int, in timeout = new timeval(-1, 0), 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.

const timeout = new timeval(4,0);
const socket = new udpSocket();
const (data, sender) = socket.recvFrom(40, timeout);
Arguments
  • bufferLen : int – number of bytes to read

  • timeout – time to wait for data to arrive.

Returns

tuple of (data, address)

Return type

tuple(:mod:`bytes <Bytes>, :type:ipAddr)`

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 = new timeval(-1, 0)) 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.

const timeout = new timeval(4,0);
const socket = new udpSocket();
const data = socket.recv(40, timeout);
Arguments
  • bufferLen : int – number of bytes to read

  • timeout – time to wait for data to arrive.

Returns

data

Return type

bytes

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 = new timeval(-1, 0)): c_ssize_t throws

Send data over socket to the provided address and return number of bytes sent if successful.

const timeout = new timeval(4,0);
const socket = new udpSocket();
const sentBytes = socket.send("hello world!":bytes, timeout);
Arguments
  • data : bytes – data to send to address

  • address : ipAddr – socket address for sending data

  • timeout – 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
proc setSockOpt(ref socket: ?t, level: c_int, optname: c_int, value: c_int) throws

Set the value of the given socket option (see setsockopt(2)) on provided tcpConn. The needed symbolic constants (SO_* etc.) are defined in the Sys.

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

Overload for setSockOpt that allows setting a bytes 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 a :type:bytes 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

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

Returns the value of the given socket option (see getsockopt) on provided tcpConn. The needed symbolic constants (SO_* etc.) are defined in Sys module.

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

Returns the value of the given socket option which is expected to be of type bytes on provided tcpConn. The needed symbolic constants (SO_* etc.) are defined in Sys module.

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

bytes

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

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

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