CC = gcc# compiler
CFLAGS = -Wall -g# compile flags
LIBS = -lpthread -lrt# libs
all: ks_client ks_server
$(CC) -o ks_client ks_client.o $(LIBS)
$(CC) -o ks_server ks_server.o $(LIBS)
$(CC) $(CFLAGS) -c $*.c
rm -f ks_server ks_client *.o *~
Link added to help with message queues:
You will design and implement a keyword search server, that will take a single keyword and a directory
name from a client and will search the keyword in all the files sitting in a given directory usingmultiple
threads. You will also implement the client program. There may be several client processes requesting
service from the server process. The client processes and the server will communicate using message
queues. The client program will be named as ks_client (keyword search client) and it will take
1. A keyword that is expressed as a single word, starting with a whitespace character and ending
with a whitespace character, not including any whitespace character in the middle. A whites-
pace character is either a <SPACE>, <TAB>, or <NEWLINE> character. There will be no
empty word specified.
2. A directory name (full path)
Hence a client program can be invoked as follows:
./ks_client keyword dirpath
A client process that is invoked with those parameters will first attach to the server master message
queue identified by a key derived from a file named by the given pathname and a nonzero integer
value. The server will use the master message queue to receive requests from the client processes.
Since you are the programmer of both the client and the server, you will decide this pathname and
the integer parameters of ftok to uniquely identify a message queue. For instance, you can use the
name of server program and the integer 1 in both client and server to create a key as follows:
See the man page of the ftok for more details on obtaining a key. See also the msgget function
to learn how to get a message queue identifier using the key returned by the ftok function.
After attaching the server master message, the client will generate a request message and include
the keyword and dirpath in that message. The generated message will be sent to the server via the
master message queue. The server must have created the master message queue earlier. Therefore,
the server must be started earlier than the client.
The name of the server program must be ks_server (keyword search server). It will take no
parameters. As in the client case, a key will be used to create the server master message queue via
the msgget function. Parameters used in ftok function should be the same in both client and the
server to connect tp the same message queue. The server will be invoked as follows:
and it will run silently in the background. The server process will not produce any output to the
screen. The output will go via message queues to the client processes. When the server process gets
a request from a client process, it will create a child process that will handle the request. The request
is just a message that is received via a message queue. The request includes the keyword and the full
path of the directory which includes multiple files to be searched. The child process that is created
will handle the request. For every file in the directory, the child process will create a corresponding
thread that will handle the search operation in that file.
The thread will search the given keyword (i.e. will try to exactly match the entire word only) in
the file that it is assigned. While searching the file, if the thread encounters the keyword as an entire
word in a line, then the thread will record the file name, line number, and the line itself (exluding the
newline character at the end) into a message. That message will be sent to the client process. If the
keyword is seen, for example, in 5 separate lines, then 5 separate messages will be created. Received
messages by the client will be printed to the screen in the following format:
For example, if the keyword is "a" and the content of the file to be searched (assume the file name
is file1.txt) is as follows:
I raised my daughter in the American
fashion; I gave her freedom, but
taught her never to dishonor her
family. She found a boy friend,
not an Italian. She went to the
movies with him, stayed out late.
Two months ago he took her for a
drive, with another boy friend.
They made her drink whiskey and
then they tried to take advantage
of her. She resisted; she kept her
honor. So they beat her like an
animal. When I went to the hospital
her nose was broken, her jaw was
shattered and held together by
wire, and she could not even weep
because of the pain.
Then, the client will print the following output to the screen:
file1.txt:4:family. She found a boy friend,
file1.txt:7:Two months ago he took her for a
If the keyword is seen more than once in a line, then a single message will be created for that line.
For example, if we had a line as "a a a", then the number of matches on this line would be 3. However,
we have to report such a line only once (i.e. generate a single message and print the line to the screen
All threads that are searching a certain file existing in the given directory will do the same thing.
Hence, they will return the result to the client process in messages via the message queue(s) that is
(are) created between the server process and that client process for sending replies. The number of
message queues that you will create for this purpose is upto you.
The client process will receive such messages. When the server finishes searching the whole tree,
it will send a special message to the client indicating the end of the search operation. Similarly,
a special keyword called exit will be used to shut-down the server. When server receives the exit
keyword, then it will not search that keyword but remove the master message queue and terminate.
Similarly, the client will not wait output messages from the server if the exit keyword is sent to the
The user should be able to start up more than one client at the same time. In this way, several
search requests may arrive to the server at the same time and the server has to create several child
processes in this case. Each child process will handle one client’s request. Handling a request may
cause several threads to be created from that child process.
Constants and Tips
You can make the following assumptions on the keyword size, directory path size, line size, and the
final result size in terms of the number of characters they include:
1. KEYWORDSIZE = 32
2. DIRPATHSIZE = 128
3. LINESIZE = 1024
4. RESULTSIZE = 2048
Also, remember to use thread-safe library functions inside your threads! (for instance strtok_r()
instead of strtok()).
What to Submit
1. ks_client.c: including the source code of the client.
2. ks_server.c: including the source code of the server.