Often a process has to
deal with multiple input streams. For example, a server may have to
listen on multiple ports, each of which corresponds to a different
type of clients. In the case of Linux, a super server called
xinetd is running to service all types of
requests such as
ssh, finger and others. (Read
man xinetd for more information.) A server can
create and listen on multiple sockets, each of which is for
one type of service. When there is an in-coming request, a system
select (or similar calls in other systems)
can help determine which of the multiple sockets has data ready for
read. Based on this condition, the server can take (read) information
from that particular socket and work from there.
select Work: The system call
with a piece of data structure called
fd_set which is
essentially a collection of bits. If one of the input streams is ready
(has data), the corresponding bit will be set by the operating
select call will return the number of streams that are ready as
result. When the call is returned, the calling program can select the
stream that is ready and continue the process with that stream. When
multiple inputs are ready, the calling program can deal with them one
at a time.
The utmp database: Like many modern computing systems, Linux keeps track of information about its users, in particular, who are currently using the system. By keeping these information, the Linux operating system can respond to commands such as
finger (if you have never used these commands, read these manual pages, and give these commands a try.) Linux keeps a database of these information in a file called
utmp (for user temporary files.) Your second task today is to learn to work with this file and extract user information from this file. Once becoming familiar with the
utmp, you are asked to integrate this service as a part of a super server.
Create a directory in your git repository called lab05, as in
Also create on your local file system the directory of lab05 under your CSCI 363 course work directory. Copy all files from
~cs363/Spring16/student/labs/lab05/ to your own lab directory. You should see a collection of seven files,
echoClient.c, getwho.c, Makefile, superServer.c, tcplib.c, tcplib.h, and
timeClient-udp.c, from which you are to create your solution.
Your first task is to read the code
superServer.c and understand the general flow of this server program. Then you need to fill in the details where the macro FD_SET and its related calls, and the system call select to complete the program. The places you need to add code are highlighted by the TODO comments.
Create an answers.txt and write a paragraph or two describing what the macros
FD_SET() do, what the system call
select() does, and how it works. Consult the relevant manual pages if needed. Note that there is a complete program example towards the end of the manual page.
Once the superServer program works, it should be able to serve two types of clients, a time service that returns the system time, and an echo service that echo the client input.
Compile and run
this set of clients and server to see how they work. Note: before you compile the program, change the port numbers in the programs to your assigned port numbers. You should
run the server first, then run the
actually typing a line of input to the client program so the client program
doesn't quit before you run the time client. The point here is to
demonstrate that the server is actually able to handle multiple
clients simultaneously. While the
echoClient is running (that is, you started the echo client without typing a line to it), try also the
timeClient-udp which is supposed to get a time reading from the server and displays on the client's screen. In this example, the time client actually is a UDP client. This means that a super server can deal with multiple UDP and TCP clients, simultaneously. After running the time client, type a line of text as input to the echo client program. Both clients should be completed and exit now.
As described in the Introduction section of the lab, the Linux operating systems keeps information about current users in a database called
utmp from which programs can access current user information. The
utmp database essentially is a collection of records of the type
struct utmp (read the manual page on utmp to find out the details.) The program
getwho.c goes through the entire list of current users and counts how many records are in the database. Your task is to print out the user name (
ut_user) based on the user type (
ut_type.) You are asked to print only the normal user process (
USER_PROCESS.) You are asked to revise the
getwho.c program so that not only does the program print the counts (which it already does), but also print out the user name who are currently on the system.
Before actually coding, you probably should read the manual pages for the three library calls used in the program, that is,
setutent(), getutent() and
Once your program can correctly print who is currently on your local computer, try the program on a server such as linuxremote to see who are on those computers.
getwhoas a part of the super server
Now that your program
getwho.c works correctly, revise the
superServer.c so that
getwho will be a part of the service. Here are a few notes about the integration.
getwho.cprogram into a string with a new line character after each user name. When a client requests a getwho service to the server, the server should return a list of user names who are currently on the server one user per line, e.g.,
user 1 user 2 user 3
Submit all your program files and the answers.txt to your gitlab repository. The files should be complete so that I can compile and run your programs without copying other extra files. You should have the following in your submission.
Congratulations, you've finished this lab!