Next: , Previous: Network Socket Address, Up: Networking


6.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 Ports and File Descriptors.

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

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

— 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). The return value is unspecified.

          (connect sock AF_INET INADDR_LOCALHOST 23)
          (connect sock (make-socket-address AF_INET INADDR_LOCALHOST 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, ie. 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-object 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
— 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, wait until one is available (unless the non-blocking option has been set on the socket).

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

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, ie. 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 string 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 the string message on a 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 str [flags [start [end]]]
— C Function: scm_recvfrom (sock, str, flags, start, end)

Return data from the socket port sock and also information about where the data was received from. sock must already be bound to the address from which data is to be received. str, is a string into which the data will be written. The size of str 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 a pair: the CAR is the number of bytes read from the socket and the CDR an address object in the same form as returned by accept. The address will given as #f if not available, as is usually the case for stream sockets.

The start and end arguments specify a substring of str to which the data should be written.

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

— 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 the string message as a datagram on 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.

The following functions can be used to convert short and long integers between “host” and “network” order. Although the procedures above do this automatically for addresses, the conversion will still need to be done when sending or receiving encoded integer data from the network.

— Scheme Procedure: htons value
— C Function: scm_htons (value)

Convert a 16 bit quantity from host to network byte ordering. value is packed into 2 bytes, which are then converted and returned as a new integer.

— Scheme Procedure: ntohs value
— C Function: scm_ntohs (value)

Convert a 16 bit quantity from network to host byte ordering. value is packed into 2 bytes, which are then converted and returned as a new integer.

— Scheme Procedure: htonl value
— C Function: scm_htonl (value)

Convert a 32 bit quantity from host to network byte ordering. value is packed into 4 bytes, which are then converted and returned as a new integer.

— Scheme Procedure: ntohl value
— C Function: scm_ntohl (value)

Convert a 32 bit quantity from network to host byte ordering. value is packed into 4 bytes, which are then converted and returned as a new integer.

These procedures are inconvenient to use at present, but consider:

     (define write-network-long
       (lambda (value port)
         (let ((v (make-uniform-vector 1 1 0)))
           (uniform-vector-set! v 0 (htonl value))
           (uniform-vector-write v port))))
     
     (define read-network-long
       (lambda (port)
         (let ((v (make-uniform-vector 1 1 0)))
           (uniform-vector-read! v port)
           (ntohl (uniform-vector-ref v 0)))))