NAME
net - standard networking module
NETWORK SERVICES
This chapter is dedicated to the AFNIX networking services. It
assumes that the reader has a basic knowledge of the Internet Protocol
or IP. The AFNIX implementation provides, in a single module called
afnix-net, all classes and functions needed to perform IP operations,
create server or clients programs. This module is also designed to
support IP version 6 with certain platforms. All AFNIX networking
objects are located in the afnix-net module. This module must be loaded
prior any operation. Multiple calls to the module initialization
routine are harmless. The interpreter method module loads a specific
module by name. When the module has been loaded, the object are
available in the afnix:net nameset.
interp:library "afnix-net"
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 AFNIX implementation supports both versions.
127.0.0.1 # ipv4 localhost
0:0:0:0:0:0:0:1 # ipv6 localhost
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 AFNIX 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 afnix:net: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.
# load network module
interp:library "afnix-net"
# get the localhost address
const addr (afnix:net:Address "localhost")
# print the ip address
println (addr:get-address)
As another example, the afnix:sys: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.
# print the ip address information of the arguments
# usage: axi XNET001.als [hosts ...]
# get the network module
interp:library "afnix-net"
# print the ip address
const ip-address-info (host) {
try {
const addr (afnix:net:Address host true)
println "host name : " (addr:get-name)
println " ip address : " (addr:get-address)
println " canonical name : " (addr:get-canonical-name)
# get aliases
const size (addr:get-alias-size)
loop (trans i 0) (< i size) (i:++) {
println " alias address : " (addr:get-alias-address i)
println " alias name : " (addr:get-alias-name i)
}
} (errorln "error: " what:reason)
}
# get the hosts
for (s) (interp:argv) (ip-address-info s)
zsh> axi net-0001.als localhost
host name : localhost
ip address : 127.0.0.1
canonical name : localhost
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 AFNIX 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.
assert 13 (afnix:net:get-tcp-service "daytime")
assert 13 (afnix:net:get-udp-service "daytime")
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 Input and
Output 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.
# get the network module
interp:library "afnix-net"
# get the daytime server port
const port (afnix:net:get-tcp-service "daytime")
# create a tcp client socket
const s (afnix:net:TcpClient "localhost" port)
# read the data - the server close the connection
while (s:valid-p) (println (s:readln))
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.
zsh> axi 3201.als www.afnix.org
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.
# fetch an html page by host and page
# usage: axi 3203.als [host] [page]
# get the network module
interp:library "afnix-net"
interp:library "afnix-sys"
# connect to the http server and issue a request
const send-http-request (host page) {
# create a client sock on port 80
const s (afnix:net:TcpClient host 80)
const saddr (s:get-socket-address)
# format the request
s:writeln "GET " page " HTTP/1.1"
s:writeln "Host: " (saddr:get-canonical-name)
s:writeln "Connection: close"
s:writeln "User-Agent: afnix tcp client example"
s:newline
# write the result
while (s:valid-p) (println (s:readln))
}
# get the argument
if (!= (interp:argv:length) 2) (afnix:sys:exit 1)
const host (interp:argv:get 0)
const page (interp:argv:get 1)
# send request
send-http-request host page
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.
# get the libraries
interp:library "afnix-net"
interp:library "afnix-sys"
# get the daytime server port
const port (afnix:net:get-udp-service "time")
# create a client socket and read the data
const print-time (host) {
# create a udp client socket
const s (afnix:net:UdpClient host port)
# send an empty datagram
s:write
# read the 4 bytes data and adjust to epoch
const buf (s:read 4)
const val (- (buf:get-quad) 2208988800)
# format the date
const time (afnix:sys:Time val)
println (time:format-date) ’ ’ (time:format-time)
}
# check for one argument or use localhost
const host (if (== (interp:argv:length) 0)
"localhost" (interp:argv:get 0))
print-time host
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.
# create a client socket and read the data
const print-time (host) {
# create a udp client socket
const s (afnix:net:UdpClient host port)
# send an empty datagram until the socket is valid
s:write
# retransmit datagram each second
while (not (s:valid-p 1000)) (s:write)
# read the 4 bytes data and adjust to epoch
const buf (s:read 4)
const val (- (buf:get-quad) 2208988800)
# format the date
const time (afnix:sys:Time val)
println (time:format-date) ’ ’ (time:format-time)
}
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.
# create a client socket and read the data
const print-socket-info (host) {
# create a tcp client socket
const s (afnix:net:TcpClient host port)
# print socket address and port
const saddr (s:get-socket-address)
const sport (s:get-socket-port)
println "socket ip address : " (saddr:get-address)
println "socket canonical name : " (saddr:get-canonical-name)
println "socket port : " sport
# print peer address and port
const paddr (s:get-peer-address)
const pport (s:get-peer-port)
println "peer ip address : " (paddr:get-address)
println "peer canonical name : " (paddr:get-canonical-name)
println "peer port : " pport
}
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.
trans s (afnix:net:TcpServer)
trans s (afnix:net:TcpServer 8000)
trans s (afnix:net:TcpServer 8000 5)
trans s (afnix:net:TcpServer "localhost" 8000)
trans s (afnix:net:TcpServer "localhost" 8000 5)
trans s (afnix:net:TcpServer (Address "localhost") 8000)
trans s (afnix:net:TcpServer (Address "localhost") 8000 5)
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.
# get the network module
interp:library "afnix-net"
# create a tcp server on port 8000
const srv (afnix:net:TcpServer 8000)
# wait for a connection
const s (srv:accept)
# echo the line until the end
while (s:valid-p) (s:writeln (s:readln))
The telnet session is then quite simple. The line hello world is echoed
by the server.
zsh> telnet localhost 8000
Trying 127.0.0.1...
Connected to localhost.
Escape character is ’^]’.
hello world
^D
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.
# get the network module
interp:library "afnix-net"
# this function echo a line from the client
const echo-server (s) {
while (s:valid-p) (s:writeln (s:readln))
}
# create a tcp server on port 8000
const srv (afnix:net:TcpServer 8000)
# wait for a connection
while true {
trans s (srv:accept)
launch (echo-server s)
}
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.
trans s (afnix:net:UdpServer)
trans s (afnix:net:UdpServer 8000)
trans s (afnix:net:UdpServer "localhost" 8000)
trans s (afnix:net:UdpServer (Address "localhost") 8000)
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.
# get the network module
interp:library "afnix-net"
# create a udp server on port 8000
const srv (afnix:net:UdpServer 8000)
# wait for a connection
while true {
trans dg (srv:accept)
dg:writeln (dg:readln)
}
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.
# wait for a datagram
trans dg (s:accept)
# assert datagram type
assert true (datagram-p dg)
# get contents length
println "datagram buffer size : " (dg:get-buffer-length)
# read a line from this datagram
trans line (dg:readln)
# send it back to the sender
s:writeln line
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 AFNIX 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.
# create an address and a tcp socket
const addr (afnix:net:Address "localhost")
const sid (afnix:net:TcpSocket)
# connect the socket
sid:connect 13 addr
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.
# create an address and a tcp socket
const addr (afnix:net:Address "localhost")
const sid (afnix:net:TcpSocket)
# disable the naggle algorithm
sid:set-option sid:NO-DELAY true
# connect the socket
sid:connect 13 addr
MAIL SERVICES
This chapter is dedicated to the mail delivery subsystem, which is part
of the standard network module. The mail delivery is built around a
class that handle that can operate as a simple MTA.
Mail delivery
The Mail class is a mail delivery object which manages to contact a
Mail Transport Agent or MTA, in order to deliver a message to one or
several recipients. By default, the object contacts the local MTA, but
this behavior can be changed with the set-mta-address method. The class
implements the recipient address syntax as specified by RFC822.
Simple mail example
At construction, the instance is empty. Only the recipient address
needs to be specified. The send method send the message by contacting
the MTA. If an error occurs, an exception is raised.
# get the network module
interp:library "afnix-net"
# create an empty mail
const mail (afnix:met:Mail)
# add the recipient address
mail:to "me@domain.org"
# send the message
mail:send
An empty message is sent to (@domain.org) @domain.org. By default, the
subject is initialized to "no subject".
Recipient address format
RFC822 defines the recipient address format. The simplest one is a
local user or a qualified name with a domain. The Mail object takes
care of detecting the presence of the < and > characters. If a string
precedes the address, the enclosed address is used to communicate with
the MTA, but the original one is placed in the header. The following
example illustrates various address format.
mail:to "me"
mail:to "<me>"
mail:to "me@domain.org"
mail:to "<me@domain.org>"
mail:to "user <me@domain.org>, other <other@domain.org>"
The to method adds an address to the direct recipient list. Several
call to this method or several address in one call can be made. In the
case of multiple addresses in one call, a coma ’,’ is used as the
address separator. The cc method adds one or several addresses to the
recipients copy list. This list is also added in the header. The bcc
method adds one or several addresses to the recipient blind copy list.
This list is not included in the header.
Message content
The message is built by specifying the subject and filling the message
buffer. The subject method take a string argument to be used as the
message subject. The add and addln methods add one or several literals
to the message buffer. The addln method adds a new-line character at
the end. Because literals are used with this method, multiple arguments
can be used as well as native representation. This method behaves like
the write method of an output stream.
# set message subject
mail:subject "a simple mail demo"
# add a line in the message buffer
mail:add "This line is a text added to the message"
mail:addln "a simple number: " 123 "is automatically converted"
Message delivery
The send method contacts the MTA and request a message delivery.
Example 3303.als illustrates a complete use of the Mail class.
# send an email to yourself
# get the libraries
interp:library "afnix-sys"
interp:library "afnix-net"
# get your user name
const user-name (afnix:sys:get-user-name)
# prepare the mail
const mail (afnix:net:Mail)
mail:to user-name
mail:subject "hello from afnix example"
mail:addln "This is a generated message from the Afnix"
mail:addln "mail object - Enjoy the ride"
mail:addln "The Afnix team"
# send the mail
mail:send
NETWORKING REFERENCE
This appendix is a reference of the AFNIX standard networking module.
Symbol Description
afnix-net module
afnix:net nameset
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.
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
InputOutput
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.
read -> Character (none)
The read method returns the next character available from the
socket. If the socket has been closed, the eof character is
returned.
read -> Buffer (Integer)
The read method with an integer argument returns a buffer of
characters by reading the socket. The number of read characters
might be less than requested. Use the length method to check for
the returned buffer size.
readln -> String (none)
The readln method returns the next line available from the
socket. If the socket has been closed, the eof character is
returned.
write -> none (Literal+)
The write method write one or more literal arguments on the
socket. This method returns nil.
writeln -> none (Literal)
The writeln method write one or more literal argument to the
socket and finish with a newline. This method return nil.
newline -> none (none)
The newline method writes a new line character to the socket.
The method returns nil.
close -> Boolean (none)
The close method close the socket and returns true on success,
false otherwise. In case of success, multiple calls return true.
valid-p -> Boolean (none|Integer)
The valid-p method returns true if the socket is in a valid
state. By valid state, we mean that the socket can read a
character. With one argument, the method timeout after the
specified time.
eof-p -> Boolean (none)
The eof-p method returns true if no more characters can be read
from this socket or the socket has been closed.
pushback -> none (Character|String)
The pushback method pushback a character or a string in the
input stream. Subsequent calls to read will return the last
pushed characters. Pushing a string is equivalent to push each
characters of the string.
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-address method returns the port number 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-socket-address method returns the port number 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.
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 UdpSocketaccept 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.
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.
MAIL SERVICES REFERENCE
Mail
The Mail class is a mail delivery object which manages to contact a
Mail Transport Agent or MTA in order to deliver a message to one or
several recipients. By default, the object contacts the local MTA, but
this behavior can be changed with the set-mta-address method. The class
implements the recipient an address syntax scheme as specified by
RFC822. At construction, the instance is empty. Only the recipient
address needs to be specified. The send method send the message by
contacting the MTA. If an error occurs, an exception is raised.
Predicate
mail-p
Inheritance
Object
Constructors
Mail (none)
The Mail constructor create a a default message which is empty.
The recipient addresses and the subject must be specified for a
successful message delivery.
Methods
to -> none (String)
The to method adds one or several address to the destination
list. The address format must conform to RFC822. Multiple
address are coma separated. Multiple call to this method is
possible.
cc -> none (String)
The cc method adds one or several address to the copy list. The
address format must conform to RFC822. Multiple address are coma
separated. Multiple call to this method is possible.
bcc -> none (String)
The bcc method adds one or several address to the blind copy
list. The address format must conform to RFC822. Multiple
address are coma separated. Multiple call to this method is
possible. The blind copy list is not included in the message
header.
add -> none (String ...)
The add method adds one or several literals to the message
buffer. This is the normal way to fill a message buffer by
string line.
addln -> none (String ...)
The addln method adds one or several literals to the message
buffer. A newline character is added at the end of the line.
This is a similar way to fill a message buffer by string line.
send -> none (none)
The send method request a message delivery by contacting the
MTA. Once the MTA has been contacted, the message header and the
message body is transferred. The MTA is responsible to deliver
the message to the appropriate recipients.
subject -> none (String)
The subject method sets the message subject string line.
set-mta-address -> none (String)
The set-mta-address method sets the MTA IP address that the
class needs to contact for mail request. The address can be an
fully qualified host name or an IP number.
get-mta-address -> String (none)
The get-mta-address method returns the current MTA IP address
for this mail object.
set-mta-port -> none (Integer)
The set-mta-port method set the current MTA IP port number for
this mail object. With the MTA IP address, the MTA to contact
for mail request is uniquely defined. The default port value is
25.
get-mta-port -> Integer (none)
The get-mta-port method returns the current MTA IP port number
for this mail object. The default port value is 25.