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
call 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.
How Does select
Work: The system call
select
works
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
system. The select
call will return the number of streams that are ready as
result. When the call is returned, the calling program can select the
input
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 who
, w
, and 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
~/csci363/labs/lab05
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_ZERO()
and 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 echoClient
without
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.
utmp
databaseAs 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 endutent()
.
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.
getwho
as a part of the super serverNow 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.
tcplib
.getwho.c
program 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.
Makefile
.script
command.Congratulations, you've finished this lab!