The History of UICI
Back in the 1980's when we first started teaching networking in OS we used
sockets.
Student found it quite difficult to write working programs, and only a small
fraction of the class could write a server and a client that could communicate.
In the fall of 1991, I tried to teach TLI, a different neworking interface
that has its origins with AT&T UNIX.
This was even more difficult for the students.
For the final exam, I wanted to determine whether the students grasped the
ideas behind client-server communication. It was not feasible for them
to write a program using TLI on the final, so I made up a simpler interface
and called it UICI. The final exam problem appears below.
At this point, UICI had not been implemented. It was just a theoretical
interface to sockets. In the following semester, spring 1992, I implemented
a version of UICI using sockets. The first version was very similar to
what appears in the problem below.
The current version of UICI is not much different from the one in the final
exam problem. You will recognize u_accept as a combination of u_listen
and u_remote below. The current u_connect does not need to first call u_open.
Also, there is no need for u_error or u_close, since perror and close can be
used with the current implementation of UICI.
The problem below was problem 9 on my final exam in Fall 1991.
The exam
lasted 2 hours and 45 minutes and this problem was 25% of the exam, so
students had about 45 minutes to complete this problem. Remember, that this
was the first time they (or anyone else for that matter) had seen the
UICI interface. Notice the old format for the parameters of C functions.
In 1991, our students were not using an ANSI C compiler.
-
(25 points) The Universal Standards Organization has determined that
the Transport Layer Interface (TLI) is much too complicated and has
proposed the following Universal Internet Communication Interface, UICI,
(pronounced U-ickky) to replace it.
A summary of the UICI routines is attached.
- Write a server program which will wait for communication from one
remote host on port number 12345.
It will then write the name of the remote host
to standard output, send the message "Hi there\n" to the remote host,
wait for a message in reply, write that message to standard output,
close communication, and exit.
If an error occurs, an appropriate message
should be sent to standard error and the program should exit.
- Write a client program which will initiate communication with one
remote host on port number 12345.
The host name is given on the command line of
the client program. After communication has been established,
it should wait for a message from the remote host,
write that message to standard
output, send the message "How are you?\n" to the remote host,
close communication and exit.
If an error occurs, an appropriate message should
be sent to standard error and the program should exit.
Here is a summary of the UICI routines that are available:
int u_open(port)
unsigned short port;
This replaces t_open and t_bind. It returns a file descriptor which
is bound to given port number. -1 is returned if an error occurs.
int u_listen(fd)
int fd;
This is used by the server to listen for a communication and
replaces t_listen and t_accept. It blocks until a remote request
is received for the port bound to the given file descriptor.
A new file descriptor is returned which can be used with the
standard read and write UNIX system calls to communicate with the
remote host. -1 is returned if an error occurs.
int u_connect(fd,inetp)
int fd;
char *inetp;
This is used by the client to initiate communication with a remote
server and replaces t_connect. fd is a file descriptor previously
opened with u_open and inetp is a pointer to a character string
giving the internet name of the remote machine, e.g.
   inetp = "ring20"
-1 is returned if an error occurs. If no error occurs, fd can be
used with the standard UNIX read and write system calls to
communicate with the remote host.
int u_close(fd)
int fd;
This closes communication. -1 is returned if fd was not opened
with u_open.
int u_remote(fd,inetp)
int fd;
char *inetp;
This sets the character string pointed to by inetp to the internet name
of the remote host after communication has been established. It can be
used by the server to determine the name of the remote host requesting
communication. Before the call, inetp must be pointing to a string
which is large enough to hold the internet name. It returns -1 if
an error occurs.
void u_error(msg)
char *msg;
This routine may be called after any of the above routines returns
and error. It writes msg to standard error followed an error
message describing the last UICI error.