| Standard Networking Module

Standard Networking Module

The Standard Networking module is an original implementation of networking facilities for the Internet Protocol. The module features standard TCP and UDP sockets for point to point communication as well as multicast socket. Numerous functions and objects for address manipulation are also included in this module. This module is also designed to support IP version 6 with certain platforms.

IP address

The IP based communication uses a standard address to reference a particular peer. With IP version 4, the standard dot notation is with 4 bytes. With IP version 6, the standard semicolon notation is with 16 bytes. The current implementation supports both versions.

IP address architecture and behavior are described in various documents as listed in the bibliography.

Domain name system

The translation between a host name and an IP address is performed by a resolver which uses the Domain Name System or DNS. Access to the DNS is automatic with the implementation. Depending on the machine resolver configuration, a particular domain name translation might result in an IP version 4 or IP version 6 address. Most of the time, an IP version 4 address is returned.

The mapping between an IP address and a host name returns the associated canonical name for that IP address. This is the reverse of the preceding operation.

The Address class

The `Address` class allows manipulation of IP address. The constructor takes a string as its arguments. The argument string can be either an IP address or a host name which can be qualified or not. When the address is constructed with a host name, the IP address resolution is done immediately.

Name to address translation

The most common operation is to translate a host name to its equivalent IP address. Once the `Address` object is constructed, the `get-address` method returns a string representation of the internal IP address. The following example prints the IP address of the localhost, that is 127.0.0.1 with IP version 4.

As another example, the `get-host-name` function returns the host name of the running machine. The previous example can be used to query its IP address.

Address to name translation

The reverse operation of name translation maps an IP address to a canonical name. It shall be noted that the reverse lookup is not done automatically, unless the reverse flag is set in the constructoor. The `get-canonical-name` method of the `Address` class returns such name. Example `XNET001.als` is a demonstration program which prints the address original name, the IP address and the canonical name. Fell free to use it with your favorite site to check the equivalence between the original name and the canonical name.

Address operations

The `Address` class provides several methods and operators that ease the address manipulation in a protocol indepedant way. For example, the `==` operator compares two addresses. The `++` operator can also be used to get the next IP address.

Transport layers

The two transport layer protocols supported by the Internet protocol is the TCP, a full-duplex oriented protocol, and UDP, a datagram protocol. TCP is a reliable protocol while UDP is not. By reliable, we mean that the protocol provides automatically some mechanisms for error recovery, message delivery, acknowledgment of reception, etc... The use of TCP vs. UDP is dictated mostly by the reliability concerns, while UDP reduces the traffic congestion.

Service port

In the client-server model, a connection is established between two hosts. The connections is made via the IP address and the port number. For a given service, a port identifies that service at a particular address. This means that multiple services can exist at the same address. More precisely, the transport layer protocol is also used to distinguish a particular service. The network module provides a simple mechanism to retrieve the port number, given its name and protocol. The function `get-tcp-service` and `get-udp-service` returns the port number for a given service by name. For example, the daytime server is located at port number 13.

Host and peer

With the client server model, the only information needed to identify a particular client or server is the address and the port number. When a client connects to a server, it specify the port number the server is operating. The client uses a random port number for itself. When a server is created, the port number is used to bind the server to that particular port. If the port is already in use, that binding will fail. From a reporting point of view, a connection is therefore identified by the running host address and port, and the peer address and port. For a client, the peer is the server. For a server, the peer is the client.

TCP client socket

The `TcpClient` class creates an TCP client object by address and port. The address can be either a string or an `Address` object. During the object construction, the connection is established with the server. Once the connection is established, the client can use the `read` and `write` method to communicate with the server. The `TcpClient` class is derived from the `Socket` class which is derived from the `InputStream` and `OutputStream` classes.

Day time client

The simplest example is a client socket which communicates with the daytime server. The server is normally running on all machines and is located at port 13.

Example `3201.als` in the example directory prints the day time of the local host without argument or the day time of the argument. Feel free to use it with www.afnix.org. If the server you are trying to contact does not have a day time server, an exception will be raised and the program terminates.

HTTP request example

Another example which illustrates the use of the `TcpClient` object is a simple client which download a web page. At this stage we are not concern with the URL but rather the mechanics involved. The request is made by opening a TCP client socket on port 80 (the HTTP server port) and sending a request by writing some HTTP commands. When the commands have been sent, the data sent by the server are read and printed on the standard output. Note that this example is not concerned by error detection.

UDP client socket

UDP client socket is similar to TCP client socket. However, due to the unreliable nature of UDP, UDP clients are somehow more difficult to manage. Since there is no flow control, it becomes more difficult to assess whether or not a datagram has reached its destination. The same apply for a server, where a reply datagram might be lost. The `UdpClient` class is the class which creates a UDP client object. Its usage is similar to the `TcpClient`.

The time client

The UDP time server normally runs on port 37 is the best place to enable it. A UDP client is created with the `UdpClient` class. Once the object is created, the client sends an empty datagram to the server. The server send a reply datagram with 4 bytes, in network byte order, corresponding to the date as of January 1st 1900. Example `3204.als` prints date information after contacting the local host time server or the host specified as the first argument.

This example calls for several comments. First the `write` method without argument sends an empty datagram. It is the datagram which trigger the server. The `read` method reads 4 bytes from the reply datagram and places them in a `Buffer` object. Since the bytes are in network byte order, the conversion into an integer value is done with the `get-quad` method. Finally, in order to use the `Time` class those epoch is January 1st 1970, the constant `2208988800` is subtracted from the result. Remember that the time server sends the date in reference to January 1st 1900. More information about the time server can be found in RFC738.

More on reliability

The previous example has some inherent problems due to the unreliability of UDP. If the first datagram is lost, the `read` method will block indefinitely. Another scenario which causes the `read` method to block is the loss of the server reply datagram. Both problem can generally be fixed by checking the socket with a timeout using the `valid-p` method. With one argument, the method timeout and return false. In this case, a new datagram can be send to the server. Example `3205.als` illustrates this point. We print below the extract of code.

Note that this solution is a naive one. In the case of multiple datagrams, a sequence number must be placed because there is no clue about the lost datagram. A simple rule of thumb is to use TCP as soon as reliability is a concern, but this choice might not so easy.

Error detection

Since UDP is not reliable, there is no simple solution to detect when a datagram has been lost. Even worse, if the server is not running, it is not easy to detect that the client datagram has been lost. In such situation, the client might indefinitely send datagram without getting an answer. One solution to this problem is again to count the number of datagram re-transmit and eventually give up after a certain time.

Socket class

The `Socket` class is the base class for both `TcpClient` and `UdpClient`. The class provides methods to query the socket port and address as well as the peer port and address. Note at this point that the UDP socket is a connected socket. Therefore, these methods will work fine. The `get-socket-address` and `get-socket-port` returns respectively the address and port of the connected socket. The `get-peer-address` and `get-peer-port` returns respectively the address and port of the connected socket's peer. Example `3206.als` illustrates the use of these methods.

Socket predicates

The `Socket` class is associated with the `socket-p` predicate. The respective client objects have the `tcp-client-p` predicate and `udp-client-p` predicate.

TCP server socket

The `TcpServer` class creates an TCP server object. There are several constructors for the TCP server. In its simplest form, without port, a TCP server is created on the `localhost` with an ephemeral port number (i.e port 0 during the call). With a port number, the TCP server is created on the `localhost`. For a multi-homed host, the address to use to run the server can be specified as the first argument. The address can be either a string or an `Address` object. In both cases, the port is specified as the second argument. Finally, a third argument called the `backlog` can be specified to set the number of acceptable incoming connection. That is the maximum number of pending connection while processing a connection. The following example shows various ways to create a TCP server.

Echo server example

A simple echo server can be built and tested with the standard `telnet` application. The application will echo all lines that are typed with the `telnet` client. The server is bound on the port 8000, since ports 0 to 1024 are privileged ports.

The `telnet` session is then quite simple. The line hello world is echoed by the server.

The accept method

The previous example illustrates the mechanics of a server. When the server is created, the server is ready to accept connection. The `accept` method blocks until a client connect with the server. When the connection is established, the `accept` method returns a socket object which can be used to read and write data.

Multiple connections

One problem with the previous example is that the server accepts only one connection. In order to accept multiple connection, the `accept` method must be placed in a loop, and the server operation in a thread (There are some situations where a new process might be more appropriate than a thread). Example `3302.als` illustrates such point.

UDP server socket

The `UdpServer` class is similar to the `TcpServer` object, except that there is no backlog parameters. In its simplest form, the UDP server is created on the `localhost` with an ephemeral port (i.e port 0). With a port number, the server is created on the `localhost`. For a multi-homed host, the address used to run the server can be specified as the first argument. The address can be either a string or an `Address` object. In both cases, the port is specified as the second argument.

Echo server example

The echo server can be revisited to work with udp datagram. The only difference is the use of the `accept` method. For a UDP server, the method return a `Datagram` object which can be used to read and write data.

Datagram object

With a UDP server, the `accept` method returns a `Datagram` object. Because a UDP is connection-less, the server has no idea from whom the datagram is coming until that one has been received. When a datagram arrives, the `Datagram` object is constructed with the peer address being the source address. Standard i/o methods can be used to read or write. When a write method is used, the data are sent back to the peer in a form of another datagram.

Input data buffer

For a datagram, and generally speaking, for a UDP socket, all input operations are buffered. This means that when a datagram is received, the `accept` method places all data in an input buffer. This means that a read operation does not necessarily flush the whole buffer but rather consumes only the requested character. For example, if one datagram contains the string hello world. A call to `readln` will return the entire string. A call to read will return only the character 'h'. Subsequent call will return the next available characters. A call like `read 5` will return a buffer with 5 characters. Subsequent calls will return the remaining string. In any case, the `get-buffer-length` will return the number of available characters in the buffer. A call to `valid-p` will return true if there are some characters in the buffer or if a new datagram has arrived. Care should be taken with the `read` method. For example if there is only 4 characters in the input buffer and a call to read for 10 characters is made, the method will block until a new datagram is received which can fill the remaining 6 characters. Such situation can be avoided by using the `get-buffer-length` and the `valid-p` methods. Note also that a timeout can be specified with the `valid-p` method.

Low level socket methods

Some folks always prefer to do everything by themselves. Most of the time for good reasons. If this is your case, you might have to use the low level socket methods. Instead of using a client or server class, the implementation let's you create a `TcpSocket` or `UdpSocket`. Once this done, the `bind`, `connect` and other methods can be used to create the desired connection.

A socket client

A simple TCP socket client is created with the `TcpSocket` class. Then the `connect` method is called to establish the connection.

Once the socket is connected, normal read and write operations can be performed. After the socket is created, it is possible to set some options. A typical one is `NO-DELAY` which disable the Naggle algorithm.

Networking reference

Address

The `Address` class is the Internet address manipulation class. The class can be used to perform the conversion between a host name and an IP address. The opposite is also possible. Finally, the class supports both IP version 4 and IP version 6 address formats.

Predicate

    address-p

Inheritance

    Object

Constructors

Address (String)

The Address constructor create an IP address object by name. The name argument is a string of a host name or a valid IP address representation.

Address (String Boolean)

The Address constructor create an IP address object by name and force the reverse lookup resolution depending on the boolean flag value. The first argument is a string of a host name or a valid IP address representation. The second argument is a boolean flag that indicates whether or not reverse lookup must occur during the construction.

Operators

== (→ Boolean) (Address)

The == operator returns true if the calling object is equal to the address argument.

!= (→ Boolean) (Address)

The != operator returns true if the calling object is not equal to the address argument.

< (→ Boolean) (Address)

The < operator returns true if the calling address is less than the address object.

<= (→ Boolean) (Address)

The <= operator returns true if the calling address is less equal than the address object.

> (→ Boolean) (Address)

The > operator returns true if the calling address is greater than the address object.

>= (→ Boolean) (Address)

The <= operator returns true if the calling address is greater equal than the address object.

++ (→ Address) (Address)

The ++ operator increments the calling address by one position.

Methods

resolve (→ String Boolean) (none)

The resolve method resolves an host name and eventually performs a reverse lookup. The first argument is a string of a host name or a valid IP address representation. The second argument is a boolean flag that indicates whether or not reverse lookup must occur during the resolution.

get-name (→ String) (none)

The get-name method returns the original name used during the object construction.

get-address (→ String) (none)

The get-address method returns a string representation of the IP address. The string representation follows the IP version 4 or IP version 6 preferred formats, depending on the internal representation.

get-vector (→ Vector) (none)

The get-vector method returns a vector representation of the IP address. The vector result follows the IP version 4 or IP version 6 preferred format, depending on the internal representation.

get-canonical-name (→ String) (none)

The get-canonical-name method returns a fully qualified name of the address. The resulting name is obtained by performing a reverse lookup. Note that the name can be different from the original name.

get-alias-size (→ Integer) (none)

The get-alias-size method returns the number of aliases for the address. The number of aliases includes as well the primary resolved name which is located at index 0.

get-alias-name (→ String) (Integer)

The get-alias-name method returns a fully qualified name of the address alias by index. The first argument is the alias index number which must be in the alias index range. The resulting name is obtained by performing a reverse lookup. Note that the name can be different from the original name. Using index 0 is equivalent to call get-canonical-name.

get-alias-address (→ String) (Integer)

The get-alias-address method returns a string representation of the IP address alias by index. The first argument is the alias index number which must be in the alias index range. The string representation follows the IP version 4 or IP version 6 preferred formats, depending on the internal representation. Using index 0 is equivalent to call get-address.

get-alias-vector (→ Vector) (Integer)

The get-alias-vector method returns a vector representation of the IP address alias by index. The first argument is the alias index number which must be in the alias index range. The vector result follows the IP version 4 or IP version 6 preferred format, depending on the internal representation. Using index 0 is equivalent to call get-vector.

Functions

get-loopback (→ String) (none)

The get-loopback function returns the name of the machine loopback. On a UNIX system, that name is localhost.

get-tcp-service (→ String) (Integer)

The get-tcp-service function returns the name of the tcp service given its port number. For example, the tcp service at port 13 is the daytime server.

get-udp-service (→ String) (Integer)

The get-udp-service function returns the name of the udp service given its port number. For example, the udp service at port 19 is the chargen server.

Socket

The `Socket` class is a base class for the AFNIX network services. The class is automatically constructed by a derived class and provide some common methods for all socket objects.

Predicate

    socket-p

Inheritance

    InputStream
    OutputStream

Constants

REUSE-ADDRESS

The REUSE-ADDRESS constant is used by the set-option method to enable socket address reuse. This option changes the rules that validates the address used by bind. It is not recommended to use that option as it decreases TCP reliability.

BROADCAST

The BROADCAST constant is used by the set-option method to enable broadcast of packets. This options only works with IP version 4 address. The argument is a boolean flag only.

DONT-ROUTE

The DONT-ROUTE constant is used by the set-option method to control if a packet is to be sent via the routing table. This option is rarely used with . The argument is a boolean flag only.

KEEP-ALIVE

The KEEP-ALIVE constant is used by the set-option method to check periodically if the connection is still alive. This option is rarely used with . The argument is a boolean flag only.

LINGER

The LINGER constant is used by the set-option method to turn on or off the lingering on close. If the first argument is true, the second argument is the linger time.

RCV-SIZE

The RCV-SIZE constant is used by the set-option method to set the receive buffer size.

SND-SIZE

The SND-SIZE constant is used by the set-option method to set the send buffer size.

HOP-LIMIT

The HOP-LIMIT constant is used by the set-option method to set packet hop limit.

MULTICAST-LOOPBACK

The MULTICAST-LOOPBACK constant is used by the set-option method to control whether or not multicast packets are copied to the loopback. The argument is a boolean flag only.

MULTICAST-HOP-LIMIT

The MULTICAST-HOP-LIMIT constant is used by the set-option method to set the hop limit for multicast packets.

MAX-SEGMENT-SIZE

The MAX-SEGMENT-SIZE constant is used by the set-option method to set the TCP maximum segment size.

NO-DELAY

The NO-DELAY constant is used by the set-option method to enable or disable the Naggle algorithm.

Methods

bind (→ none) (Integer)

The bind method binds this socket to the port specified as the argument.

bind (→ none) (Integer Address)

The bind method binds this socket to the port specified as the first argument and the address specified as the second argument.

connect (→ none) (Integer Address [Boolean])

The connect method connects this socket to the port specified as the first argument and the address specified as the second argument. A connected socket is useful with udp client that talks only with one fixed server. The optional third argument is a boolean flag that permits to select whether or not the alias addressing scheme should be used. If the flag is false, the default address is used. If the flag is true, an attempt is made to connect to the first successful address that is part of the alias list.

open-p (→ Boolean) (none)

The open-p predicate returns true if the socket is open. The method checks that a descriptor is attached to the object. This does not mean that the descriptor is valid in the sense that one can read or write on it. This method is useful to check if a socket has not been closed.

shutdown (→ Boolean) (none|Boolean)

The shutdown method shutdowns or close the connection. Without argument, the connection is closed without consideration for those symbols attached to the object. With one argument, the connection is closed in one direction only. If the mode argument is false, further receive is disallowed. If the mode argument is true, further send is disallowed. The method returns true on success, false otherwise.

ipv6-p (→ Boolean) (none)

The ipv6-p predicate returns true if the socket address is an IP version 6 address, false otherwise.

get-socket-address (→ Address) (none)

The get-socket-address method returns an address object of the socket. The returned object can be later used to query the canonical name and the ip address.

get-socket-port (→ Integer) (none)

The get-socket-port method returns the port number of the socket.

get-socket-authority (→ String) (none)

The get-socket-authority method returns the authority string in the form of an address and port pair of the socket.

get-peer-address (→ Address) (none)

The get-peer-address method returns an address object of the socket's peer. The returned object can be later used to query the canonical name and the ip address.

get-peer-port (→ Integer) (none)

The get-peer-port method returns the port number of the socket's peer.

get-peer-authority (→ String) (none)

The get-peer-authority method returns the authority string in the form of an address and port pair of the socket's peer.

set-option (→ Boolean) (constant [Boolean|Integer] [Integer])

The set-option method set a socket option. The first argument is the option to set. The second argument is a boolean value which turn on or off the option. The optional third argument is an integer needed for some options.

set-encoding-mode (→ none) (Item|String)

The set-encoding-mode method sets the input and output encoding mode. In the first form, with an item, the stream encoding mode is set directly. In the second form, the encoding mode is set with a string and might also alter the stream transcoing mode.

set-input-encoding-mode (→ none) (Item|String)

The set-input-encoding-mode method sets the input encoding mode. In the first form, with an item, the stream encoding mode is set directly. In the second form, the encoding mode is set with a string and might also alter the stream transcoing mode.

get-input-encoding-mode (→ Item) (none)

The get-input-encoding-mode method return the input encoding mode.

set-output-encoding-mode (→ none) (Item|String)

The set-output-encoding-mode method sets the output encoding mode. In the first form, with an item, the stream encoding mode is set directly. In the second form, the encoding mode is set with a string and might also alter the stream transcoing mode.

get-output-encoding-mode (→ Item) (none)

The get-output-encoding-mode method return the output encoding mode.

TcpSocket

The `TcpSocket` class is a base class for all tcp socket objects. The class is derived from the `Socket` class and provides some specific tcp methods. If a `TcpSocket` is created, the user is responsible to connect it to the proper address and port.

Predicate

    tcp-socket-p

Inheritance

    Socket

Constructors

TcpSocket (none)

The TcpSocket constructor creates a new tcp socket.

Methods

accept (→ TcpSocket) (none)

The accept method waits for incoming connection and returns a TcpSocket object initialized with the connected peer. The result socket can be used to perform i/o operations. This method is used by tcp server.

listen (→ Boolean) (none|Integer)

The listen method initialize a socket to accept incoming connection. Without argument, the default number of incoming connection is 5. The integer argument can be used to specify the number of incoming connection that socket is willing to queue. This method is used by tcp server.

TcpClient

The `TcpClient` class creates a tcp client by host and port. The host argument can be either a name or an address object. The port argument is the server port to contact. The `TcpClient` class is derived from the `TcpSocket` class. This class has no specific methods.

Predicate

    tcp-client-p

Inheritance

    TcpSocket

Constructors

TcpClient (String Integer)

The TcpClient constructor creates a new tcp client socket by host name and port number.

TcpServer

The `TcpServer` class creates a tcp server by port. An optional host argument can be either a name or an address object. The port argument is the server port to bind. The `TcpServer` class is derived from the `TcpSocket` class. This class has no specific methods. With one argument, the server bind the port argument on the local host. The backlog can be specified as the last argument. The host name can also be specified as the first argument, the port as second argument and eventually the backlog. Note that the host can be either a string or an address object.

Predicate

    tcp-server-p

Inheritance

    TcpSocket

Constructors

TcpServer (none)

The TcpServer constructor creates a default tcp server.

TcpServer (Integer)

The TcpServer constructor creates a default tcp server which is bound on the specified port argument.

TcpServer (Integer Integer)

The TcpServer constructor creates a default tcp server which is bound on the specified port argument. The second argument is the backlog value.

TcpServer (String Integer)

The TcpServer constructor creates a tcp server by host name and port number. The first argument is the host name. The second argument is the port number.

TcpServer (String Integer Integer)

The TcpServer constructor creates a tcp server by host name and port number. The first argument is the host name. The second argument is the port number. The third argument is the backlog.

Datagram

The `Datagram` class is a socket class used by udp socket. A datagram is constructed by the `UdpSocket` `accept` method. The purpose of a datagram is to store the peer information so one can reply to the sender. The datagram also stores in a buffer the data sent by the peer. This class does not have any constructor nor any specific method.

Predicate

    datagram-p

Inheritance

    Socket

UdpSocket

The `UdpSocket` class is a base class for all udp socket objects. The class is derived from the `Socket` class and provides some specific udp methods.

Predicate

    udp-socket-p

Inheritance

    Socket

Constructors

UdpSocket (none)

The UdpSocket constructor creates a new udp socket.

Methods

accept (→ Datagram) (none)

The accept method waits for an incoming datagram and returns a Datagram object. The datagram is initialized with the peer address and port as well as the incoming data.

UdpClient

The `UdpClient` class creates a udp client by host and port. The host argument can be either a name or an address object. The port argument is the server port to contact. The `UdpClient` class is derived from the `UdpSocket` class. This class has no specific methods.

Predicate

    udp-client-p

Inheritance

    UdpSocket

Constructors

UdpClient (String Integer)

The UdpClient constructor creates a new udp client by host and port. The first argument is the host name. The second argument is the port number.

UdpServer

The `UdpServer` class creates a udp server by port. An optional host argument can be either a name or an address object. The port argument is the server port to bind. The `UdpServer` class is derived from the `UdpSocket` class. This class has no specific methods. With one argument, the server bind the port argument on the local host. The host name can also be specified as the first argument, the port as second argument. Note that the host can be either a string or an address object.

Predicate

    udp-server-p

Inheritance

    UdpSocket

Constructors

UdpServer (none)

The UdpServer constructor creates a default udp server object.

UdpServer (String|Address)

The UdpServer constructor creates a udp server object by host. The first argument is the host name or host address.

UdpServer (String|Address Integer)

The UdpServer constructor creates a udp server object by host and port. The first argument is the host name or host address. The second argument is the port number.

Multicast

The `Multicast` class creates a udp multicast socket by port. An optional host argument can be either a name or an address object. The port argument is the server port to bind. The `Multicast` class is derived from the `UdpSocket` class. This class has no specific methods. With one argument, the server bind the port argument on the local host. The host name can also be specified as the first argument, the port as second argument. Note that the host can be either a string or an address object. This class is similar to the `UdpServer` class, except that the socket join the multicast group at construction and leave it at destruction.

Predicate

    multicast-p

Inheritance

    UdpSocket

Constructors

Multicast (String|Address)

The Multicast constructor creates a multicast socket object by host. The first argument is the host name or host address.

Multicast (String|Address Integer)

The Multicast constructor creates a multicast socket object by host and port. The first argument is the host name or host address. The second argument is the port number.