7.2.11.4 Network Sockets and Communication

Socket ports can be created using socket and socketpair. The ports are initially unbuffered, to make reading and writing to the same port more reliable. A buffer can be added to the port using setvbuf (see Buffering).

Most systems have limits on how many files and sockets can be open, so it’s strongly recommended that socket ports be closed explicitly when no longer required (see Ports).

Some of the underlying C functions take values in network byte order, but the convention in Guile is that at the Scheme level everything is ordinary host byte order and conversions are made automatically where necessary.

Scheme Procedure: socket family style proto
C Function: scm_socket (family, style, proto)

Return a new socket port of the type specified by family, style and proto. All three parameters are integers. The possible values for family are as follows, where supported by the system,

Variable: PF_UNIX
Variable: PF_INET
Variable: PF_INET6

The possible values for style are as follows, again where supported by the system,

Variable: SOCK_STREAM
Variable: SOCK_DGRAM
Variable: SOCK_RAW
Variable: SOCK_RDM
Variable: SOCK_SEQPACKET

proto can be obtained from a protocol name using getprotobyname (see Network Databases). A value of zero means the default protocol, which is usually right.

A socket cannot by used for communication until it has been connected somewhere, usually with either connect or accept below.

Scheme Procedure: socketpair family style proto
C Function: scm_socketpair (family, style, proto)

Return a pair, the car and cdr of which are two unnamed socket ports connected to each other. The connection is full-duplex, so data can be transferred in either direction between the two.

family, style and proto are as per socket above. But many systems only support socket pairs in the PF_UNIX family. Zero is likely to be the only meaningful value for proto.

Scheme Procedure: getsockopt sock level optname
Scheme Procedure: setsockopt sock level optname value
C Function: scm_getsockopt (sock, level, optname)
C Function: scm_setsockopt (sock, level, optname, value)

Get or set an option on socket port sock. getsockopt returns the current value. setsockopt sets a value and the return is unspecified.

level is an integer specifying a protocol layer, either SOL_SOCKET for socket level options, or a protocol number from the IPPROTO constants or getprotoent (see Network Databases).

Variable: SOL_SOCKET
Variable: IPPROTO_IP
Variable: IPPROTO_IPV6
Variable: IPPROTO_TCP
Variable: IPPROTO_UDP

optname is an integer specifying an option within the protocol layer.

For SOL_SOCKET level the following optnames are defined (when provided by the system). For their meaning see Socket-Level Options in The GNU C Library Reference Manual, or man 7 socket.

Variable: SO_DEBUG
Variable: SO_REUSEADDR
Variable: SO_STYLE
Variable: SO_TYPE
Variable: SO_ERROR
Variable: SO_DONTROUTE
Variable: SO_BROADCAST
Variable: SO_SNDBUF
Variable: SO_RCVBUF
Variable: SO_KEEPALIVE
Variable: SO_OOBINLINE
Variable: SO_NO_CHECK
Variable: SO_PRIORITY
Variable: SO_REUSEPORT
Variable: SO_RCVTIMEO
Variable: SO_SNDTIMEO

The value taken or returned is an integer.

Variable: SO_LINGER

The value taken or returned is a pair of integers (ENABLE . TIMEOUT). On old systems without timeout support (ie. without struct linger), only ENABLE has an effect but the value in Guile is always a pair.

For IP level (IPPROTO_IP) the following optnames are defined (when provided by the system). See man ip for what they mean.

Variable: IP_MULTICAST_IF

This sets the source interface used by multicast traffic.

Variable: IP_MULTICAST_TTL

This sets the default TTL for multicast traffic. This defaults to 1 and should be increased to allow traffic to pass beyond the local network.

Variable: IP_ADD_MEMBERSHIP
Variable: IP_DROP_MEMBERSHIP

These can be used only with setsockopt, not getsockopt. value is a pair (MULTIADDR . INTERFACEADDR) of integer IPv4 addresses (see Network Address Conversion). MULTIADDR is a multicast address to be added to or dropped from the interface INTERFACEADDR. INTERFACEADDR can be INADDR_ANY to have the system select the interface. INTERFACEADDR can also be an interface index number, on systems supporting that.

Last, for IPv6 level (IPPROTO_IPV6), the following optnames are defined. See man 7 ipv6 for details.

Variable: IPV6_V6ONLY

Determines whether an AF_INET6 socket is restricted to transmitting IPv6 packets only, or whether it can also transmit packets for an IPv4-mapped IPv6 address.

For IPPROTO_TCP level the following optnames are defined (when provided by the system). For their meaning see man 7 tcp.

Variable: TCP_NODELAY
Variable: TCP_CORK

The value taken or returned is an integer.

Scheme Procedure: shutdown sock how
C Function: scm_shutdown (sock, how)

Sockets can be closed simply by using close-port. The shutdown procedure allows reception or transmission on a connection to be shut down individually, according to the parameter how:

0

Stop receiving data for this socket. If further data arrives, reject it.

1

Stop trying to transmit data from this socket. Discard any data waiting to be sent. Stop looking for acknowledgement of data already sent; don’t retransmit it if it is lost.

2

Stop both reception and transmission.

The return value is unspecified.

Scheme Procedure: connect sock sockaddr
Scheme Procedure: connect sock AF_INET ipv4addr port
Scheme Procedure: connect sock AF_INET6 ipv6addr port [flowinfo [scopeid]]
Scheme Procedure: connect sock AF_UNIX path
C Function: scm_connect (sock, fam, address, args)

Initiate a connection on socket port sock to a given address. The destination is either a socket address object, or arguments the same as make-socket-address would take to make such an object (see Network Socket Address). Return true unless the socket was configured as non-blocking and the connection could not be made immediately.

(connect sock AF_INET INADDR_LOOPBACK 23)
(connect sock (make-socket-address AF_INET INADDR_LOOPBACK 23))
Scheme Procedure: bind sock sockaddr
Scheme Procedure: bind sock AF_INET ipv4addr port
Scheme Procedure: bind sock AF_INET6 ipv6addr port [flowinfo [scopeid]]
Scheme Procedure: bind sock AF_UNIX path
C Function: scm_bind (sock, fam, address, args)

Bind socket port sock to the given address. The address is either a socket address object, or arguments the same as make-socket-address would take to make such an object (see Network Socket Address). The return value is unspecified.

Generally a socket is only explicitly bound to a particular address when making a server, i.e. to listen on a particular port. For an outgoing connection the system will assign a local address automatically, if not already bound.

(bind sock AF_INET INADDR_ANY 12345)
(bind sock (make-socket-address AF_INET INADDR_ANY 12345))
Scheme Procedure: listen sock backlog
C Function: scm_listen (sock, backlog)

Enable sock to accept connection requests. backlog is an integer specifying the maximum length of the queue for pending connections. If the queue fills, new clients will fail to connect until the server calls accept to accept a connection from the queue.

The return value is unspecified.

Scheme Procedure: accept sock [flags]
C Function: scm_accept (sock)

Accept a connection from socket port sock which has been enabled for listening with listen above.

If there are no incoming connections in the queue, there are two possible behaviors, depending on whether sock has been configured for non-blocking operation or not:

  • If there is no connection waiting and the socket was set to non-blocking mode with the O_NONBLOCK port option (see fcntl), return #f directly.
  • Otherwise wait until a connection is available.

The return value is a pair. The car is a new socket port, connected and ready to communicate. The cdr is a socket address object (see Network Socket Address) which is where the remote connection is from (like getpeername below).

flags, if given, may include SOCK_CLOEXEC or SOCK_NONBLOCK, which like O_CLOEXEC and O_NONBLOCK apply to the newly accepted socket.

All communication takes place using the new socket returned. The given sock remains bound and listening, and accept may be called on it again to get another incoming connection when desired.

Scheme Procedure: getsockname sock
C Function: scm_getsockname (sock)

Return a socket address object which is the where sock is bound locally. sock may have obtained its local address from bind (above), or if a connect is done with an otherwise unbound socket (which is usual) then the system will have assigned an address.

Note that on many systems the address of a socket in the AF_UNIX namespace cannot be read.

Scheme Procedure: getpeername sock
C Function: scm_getpeername (sock)

Return a socket address object which is where sock is connected to, i.e. the remote endpoint.

Note that on many systems the address of a socket in the AF_UNIX namespace cannot be read.

Scheme Procedure: recv! sock buf [flags]
C Function: scm_recv (sock, buf, flags)

Receive data from a socket port. sock must already be bound to the address from which data is to be received. buf is a bytevector into which the data will be written. The size of buf limits the amount of data which can be received: in the case of packet protocols, if a packet larger than this limit is encountered then some data will be irrevocably lost.

The optional flags argument is a value or bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.

The value returned is the number of bytes read from the socket.

Note that the data is read directly from the socket file descriptor: any unread buffered port data is ignored.

Scheme Procedure: send sock message [flags]
C Function: scm_send (sock, message, flags)

Transmit bytevector message on socket port sock. sock must already be bound to a destination address. The value returned is the number of bytes transmitted—it’s possible for this to be less than the length of message if the socket is set to be non-blocking. The optional flags argument is a value or bitwise OR of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.

Note that the data is written directly to the socket file descriptor: any unflushed buffered port data is ignored.

Scheme Procedure: recvfrom! sock buf [flags [start [end]]]
C Function: scm_recvfrom (sock, buf, flags, start, end)

Receive data from socket port sock, returning the originating address as well as the data. This function is usually for datagram sockets, but can be used on stream-oriented sockets too.

The data received is stored in bytevector buf, using either the whole bytevector or just the region between the optional start and end positions. The size of buf limits the amount of data that can be received. For datagram protocols if a packet larger than this is received then excess bytes are irrevocably lost.

The return value is a pair. The car is the number of bytes read. The cdr is a socket address object (see Network Socket Address) which is where the data came from, or #f if the origin is unknown.

The optional flags argument is a or bitwise-OR (logior) of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.

Data is read directly from the socket file descriptor, any buffered port data is ignored.

On a GNU/Linux system recvfrom! is not multi-threading, all threads stop while a recvfrom! call is in progress. An application may need to use select, O_NONBLOCK or MSG_DONTWAIT to avoid this.

Scheme Procedure: sendto sock message sockaddr [flags]
Scheme Procedure: sendto sock message AF_INET ipv4addr port [flags]
Scheme Procedure: sendto sock message AF_INET6 ipv6addr port [flowinfo [scopeid [flags]]]
Scheme Procedure: sendto sock message AF_UNIX path [flags]
C Function: scm_sendto (sock, message, fam, address, args_and_flags)

Transmit bytevector message as a datagram socket port sock. The destination is specified either as a socket address object, or as arguments the same as would be taken by make-socket-address to create such an object (see Network Socket Address).

The destination address may be followed by an optional flags argument which is a logior (see Bitwise Operations) of MSG_OOB, MSG_PEEK, MSG_DONTROUTE etc.

The value returned is the number of bytes transmitted – it’s possible for this to be less than the length of message if the socket is set to be non-blocking. Note that the data is written directly to the socket file descriptor: any unflushed buffered port data is ignored.