Skip to content

Sockets

leftmike edited this page May 14, 2016 · 1 revision

The socket support in Foment is based on SRFI 106: Basic socket interface with one important difference: sockets are ports.

Procedures

(import (foment base)) to use these procedures.

procedure: (socket? obj)

Return #t if obj is a socket and #f otherwise.

procedure: (make-socket address-family socket-domain ip-protocol)

Return a new socket. To use this socket to listen for incoming connection requests, bind-socket, listen-socket, and accept-socket must be used. To connect this socket with a server, connect-socket must be used. address-family, socket-domain, and ip-protocol are specified below.

procedure: (bind-socket socket node service address-family socket-domain ip-protocol)

Bind socket to node and service. node must be a string. If node is the empty string, then the socket will be bound to all available IP addresses. If node is "localhost", then the socket will be bound to all available loopback addresses. service must be a string. It may be a numeric port number, for example, "80". Or it may be the name of a service, for example, "http". address-family, socket-domain, and ip-protocol are specified below.

procedure: (listen-socket socket)
procedure: (listen-socket socket backlog)

Start socket listening for incoming connections. socket must be bound using bind-socket before calling listen-socket.

procedure: (accept-socket socket)

Wait for a client to connect to the socket. A new socket will be returned which can be used to communicate with the connected client socket. socket may continue to be used with accept-socket to wait for more clients to connect. socket must be put into a listening state using listen-socket before calling accept-socket.

procedure: (connect-socket socket node service address-family socket-domain address-info ip-protocol)

Connect socket to a server. node and service must be strings. address-family, socket-domain, address-info, and ip-protocol are specified below.

procedure: (shutdown-socket socket how)

Shutdown the socket. how must be one of *shut-rd*, *shut-wr*, or *shut-rdwr*.

procedure: (send-socket socket bytevector flags)

Send the contents of bytevector on socket. flags must be 0 or *msg-oob*.

procedure: (recv-socket socket size flags)

Wait for and receive a block of data of size bytes from socket. The data will be returned as a bytevector. A zero length bytevector indicates that the peer connection is closed. flags must be 0, *msg-peek*, *msg-oob*, or *msg-waitall*.

procedure: (get-ip-addresses address-family)

Return a list of the local IP addresses in the specified address-family.

Flag Operations and Constants

These are the same as SRFI 106: Basic socket interface.

Example

This is a simple example of using sockets. The client reads a line of text, converts it to UTF-8, and sends it to the server. The server receives UTF-8, converts it to a string, and writes it.

(import (foment base))

(define (server)
    (define (loop s)
;;        (let ((bv (recv-socket s 128 0)))
;;            (if (> (bytevector-length bv) 0)
        (let ((bv (read-bytevector 128 s)))
            (if (not (eof-object? bv))
                (begin
                    (display (utf8->string bv))
                    (newline)
                    (loop s)))))
    (let ((s (make-socket (address-family inet) (socket-domain stream) (ip-protocol tcp))))
        (bind-socket s "localhost" "12345" (address-family inet) (socket-domain stream)
                (ip-protocol tcp))
        (listen-socket s)
        (loop (accept-socket s))))

(define (client)
    (define (loop s)
;;        (socket-send s (string->utf8 (read-line)) 0)
        (write-bytevector (string->utf8 (read-line)) s)
        (loop s))
    (let ((s (make-socket (address-family inet) (socket-domain stream) (ip-protocol tcp))))
        (connect-socket s "localhost" "12345" (address-family inet) (socket-domain stream)
                0 (ip-protocol tcp))
        (loop s)))

(cond
    ((member "client" (command-line)) (client))
    ((member "server" (command-line)) (server))
    (else (display "error: expected client or server on the command line") (newline)))
Clone this wiki locally