|
[Next][Prev] [Right] [Left] [Up] [Index] [Root]
Sockets may be used to establish communication channels between machines
on the same network. Once established, they can be read from or written
to in much the same ways as more familiar I/O constructs like files.
One major difference is that the data is not instantly available, so the
I/O operations take much longer than with files.
Currently sockets are only available on UNIX systems.
Strictly speaking, a socket is a communication endpoint whose
defining information consists of a network address and a port number.
(Even more strictly speaking, the communication protocol is also part of
the socket. Magma only uses TCP sockets, however, so we ignore this
point from now on.)
The network address selects on which of the available network interfaces
communication will take place; it is a string identifying the machine
on that network, in either domain name or dotted-decimal format.
For example, both "localhost" and "127.0.0.1" identify the
machine on the loopback interface (which is only accessible from the
machine itself), whereas "foo.bar.com" or "10.0.0.3" might
identify the machine in a local network, accessible from other machines
on that network.
The port number is just an integer that identifies the socket on a
particular network interface. It must be less than 65 536.
A value of 0 will indicate that the port number should be chosen
by the operating system.
There are two types of sockets, which we will call client sockets and
server sockets.
The purpose of a client socket is to initiate a connection to a
server socket, and the purpose of a server socket is to wait for
clients to initiate connections to it.
(Thus the server socket needs to be created before the client can
connect to it.)
Once a server socket accepts a connection from a client socket, a
communication channel is established and the distinction between
the two becomes irrelevant, as they are merely each side of a
communication channel.
In the following descriptions, the network address will often be
referred to as the host. So a socket is identified by a
(host, port) pair, and an established communication channel
consists of two of these pairs:
(local-host, local-port), (remote-host, remote-port).
Subsections
LocalHost: MonStgElt Default: none
LocalPort: RngIntElt Default: 0
Attempts to create a (client) socket connected to port P of host H.
Note: these are the remote values; usually it does not matter
which local values are used for client sockets, but for those rare
occasions where it does they may be specified using the parameters
LocalHost and LocalPort.
If these parameters are not set then suitable values will be chosen by
the operating system.
Also note that port numbers below 1 024 are usually reserved for
system use, and may require special privileges to be used as the
local port number.
LocalHost: MonStgElt Default: none
LocalPort: RngIntElt Default: 0
Attempts to create a server socket on the current machine, that
can be used to accept connections. The parameters LocalHost and
LocalPort may be used to specify which network interface and port
the socket will accept connections on; if either of these are not set
then their values will be determined by the operating system.
Note that port numbers below 1 024 are usually reserved for
system use, and may require special privileges to be used as the
local port number.
This may only be used on server sockets. It waits for a connection
attempt to be made, and then creates a new socket to handle the
resulting communication channel. Thus S may continue to be used
to accept connection attempts, while the new socket is used for
communication with whatever entity just connected.
Note: this new socket is not a server socket.
This routine returns the identifying information for the socket as
a pair of tuples. Each tuple is a {<host, port>} pair ---
the first tuple gives the local information and the second gives the
remote information. Note that this second tuple will be undefined for
server sockets.
Returns whether S is a server socket or not.
Due to the nature of the network, it takes significant time to transmit
data from one machine to another. Thus when a read request is begun it
may take some time to complete, usually because the data to be read has
not yet arrived. Also, data written to a socket may be broken up into
smaller pieces for transmission, each of which may take different amounts
of time to arrive.
Thus, unlike files, there is no easy way to tell if there is still more
data to be read; the current lack of data is no indicator as to whether
more might arrive.
When a read request is made on a socket, the available data is returned.
If no data is currently available, then the process waits until some
does becomes available, and returns that. (It will also return if the
socket has been closed and hence no more data can be transmitted.)
It does not continue trying to read more data, as it cannot tell whether
or not there is some "on the way".
The upshot of all this is that care must be exercised as reads may
return less data than is expected.
Max: RngIntElt Default: 0
Waits for data to become available for reading from S and then returns
it as a string. If the parameter Max is set to a positive value
then at most that many characters will be read. Note that less than
Max characters may be returned, depending on the amount of
currently available data.
If the socket has been closed then the special EOF marker string is
returned.
Max: RngIntElt Default: 0
Waits for data to become available for reading from S and then returns
it as a sequence of bytes (integers in the range 0..255).
If the parameter Max is set to a positive value then at most that
many bytes will be read. Note that less than Max bytes may be
returned, depending on the amount of currently available data.
If the socket has been closed then the empty sequence is returned.
Writes the characters of the string s to the socket S.
Writes the bytes in the byte sequence Q to the socket S. Each
byte must be an integer in the range 0..255.
Here is a trivial use of sockets to send a message from one Magma
process to another running on the same machine.
The first Magma process sets up a server socket and waits for
another Magma to contact it.
> // First Magma process
> server := Socket(: LocalHost := "localhost");
> SocketInformation(server);
<localhost, 32794>
> S1 := WaitForConnection(server);
The second Magma process establishes a client socket connection
to the first, writes a greeting message to it, and closes the socket.
> // Second Magma process
> S2 := Socket("localhost", 32794);
> SocketInformation(S2);
<localhost, 32795> <localhost, 32794>
> Write(S2, "Hello, other world!");
> delete S2;
The first Magma process is now able to continue; it reads and
displays all data sent to it until the socket is closed.
> // First Magma process
> SocketInformation(S1);
<localhost, 32794> <localhost, 32795>
> repeat
> msg := Read(S1);
> msg;
> until IsEof(msg);
Hello, other world!
EOF
[Next][Prev] [Right] [Left] [Up] [Index] [Root]
|