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.

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.

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 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: 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 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)

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

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

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 to

  • reuseAddr : 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 to

  • timeout : 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 to

  • timeout : 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 to

  • timeout : 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.addr throws

Get ipAddr associated with udp socket

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

(bytes, 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 = 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

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 = 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 address

  • address : ipAddr – socket address for sending data

  • timeout : 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 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 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  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 provided tcpConn.

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  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