The objective of this lab is to familiarize you with the sockets C API on the one hand, and the Java API on the other.
The client / server model is the canvas on which are built most distributed applications.
In this model, the server just waits for requests for connection of remote clients on a port qualified as a listening port. The communication management with each customer is taken care of by a new process or thread.
The server, freed from all communication tasks, goes back to waiting for connection requests from other clients.
Schematic diagram.
After the end of the wait on accept, if the system is using Unix processes, the server creates a child process, this last will close the listening socket, while the server will close the one of communications. The server does not take care of communication sockets to devote itself to listening to connection requests. If the system is using POSIX threads, as the sockets are shared and not duplicated, the listening and communication sockets have not to be closed.
The number of these pending requests is limited by listen, the number of communications at the same time, being limited by the number of processes that the server can create:
Note: the socket function only allocates structures from data, but does not assign a port number. This port number is explicitly assigned during the bind.
This server displays messages sent by clients on the terminal, indicating which of its children they are communicating with.
Here is the server program: Serv_TCP.c.
After modifying it, you will verify its operation by querying it using the telnet command. If the server is shut down and restarted soon after, it cannot resume the same listening port. To be able to immediately reuse this port, you must use the setsockopt () function (after creation of the socket and before the call to bind ()): setsockopt (..., SOL_SOCKET, SO_REUSEADDR, ..., ...).
Note: on some OS, you may have to add the following options at link time:
-lsocket
to load the sockets library
-lnsl
to load htons utilities ...
Here is the client code: Client_TCP.c. Check that this client is transmitting the information given to it to the server using the terminal.
We can also redirect the stdin standard input (we assume that the executable file is called Client_TCP) to simulate an input:
ls -il | Client_TCP ... ... cat * .c | Client_TCP ... ... man ls | Client_TCP ... ...
The select()
function allows an application to listen to
several sources simultaneously, that is to say to multiplex the
inputs-outputs.
We will study how a server using select()
works. It will wait for
input from the keyboard and from a few UDP ports.
For details of the select mechanism, you can refer to the
corresponding man page using the command: man -s 3c select
.
To understand the mechanism of this system call, we will complete the client and server program, the skeletons given below.
Get the server program: Serv_UDP.c and the client Client_UDP.c.
Like the previous TCP server, this UDP server basically displays messages sent by UDP clients on the terminal.
The client periodically sends datagrams to a destination whose IP address and port number have been passed on the command line.
The server we are going to build is waiting for input from: the terminal, one or more TCP ports. Here is how it works:
The use of threads is necessary to manage the simultaneous waits on these different sources of information.
Get the three files: Serv_Mux.java, Serv_Clav.java, Serv_TCP.java.
Serv_Mux.java allows to launch several threads:
Serv_TCP
to respond to a telnet
client. (Note: the lines to be modified are marked with: // MODIF TO
DO)
We will now add a listening on a UDP port. To do this, we will use a UDP server that waits for messages on port 6666 and sends the date back to the sender.
Get the file: Serv_UDP.java.
Serv_Mux
. It thus listens on the keyboard,
TCP ports and a UDP port.
Serv_Mux
.
Serv_Mux
select()
, on the same machine as the UDP client and make it wait on port 12000.
Example of traces:
Trace produced by the UDP-C client:
Sending datagram (Message sent by pid 7592 on bajazet.enst.fr) to ribouldingue
Trace produced by the UDP-Java server:
Serv_UDP-6666 will transmit: Tue Oct 02 16:45:29 GMT + 0: 00 2001 (size: 33)
Trace produced by the UDP-C server:
(33) Tue Oct 02 16:45:39 GMT + 0: 00 2001
Note: The Serv_Mux.java program performs the equivalent of the
select()
command.