This document discusses the manner in which assignment 2 will be graded for students in section 1.
Note that you must provide your own version of in_out.c
that will provide implementations of writen()
and
readline()
as discussed in the UNP text. You will want to
use these functions when writing and reading to/from sockets in your client
and server applications.
These functions should be taken from UNP section 3.9.
You will replace the #include "unp.h"
with the appropriate
system header files as demonstrated in class.
You can save typing time by downloading the UNP book source code as
shown in class and extracting the functions from the following files:
lib/writen.c lib/readline.c
Copy the functions from the above files into in_out.c and in_out.h:
Source code of writen()
and readline()
.
Function declarations and public information for writen() and readline().
Implement your client application according to the following usage statement:
Usage: prog2_client <IP-number> [<port-number>]
As such the IP number to connect to is required and the port number is optional. The default port number shall be 9880.
Note: It is implied that the socket used to connect to the server will be opened once and then used to send zero or more queries.
In this file, place your main()
and usage()
functions. It will parse the
command line arguments, open a socket to the server, execute a loop
that will prompt the user for book title, call a doQuery()
function described below for each title, print the returned author message and
ultimately close() the socket when there are no more titles.
The business logic for your client must be implemented in a function whose declaration shall be:
int doQuery(int sock, const char *title, char *author, size_t authorlen);
This function will send a newline-terminated (\n) text string given in
title
, read a text string into author
that is
no longer than authorlen
until it reaches a newline or
EOF and prune off any junk whitespace (see isspace(3)) from the end of the
response.
The proper way to pass the title
to this function is to
send it a string that has no leading or trailing whitespace. As discussed
in the manual page, things like fgets() may or may not include a trailing
newline in the text string that it reads. Therefore you must trim any off
that are present before passing it as the title to your doQuery() function.
It is required that the title text string sent to the server include a trailing \n character. The proper way to address this requirement is to add it in the doQuery() function before calling writen() OR you can call writen() to send the title string WITHOUT a trailing null character and THEN call it again to send a single \n character.
Yes. This means that your main function will remove any \n if one is present
from the user input and then doQuery()
will add one back on again. This may
seem odd but it is the most sensible thing to do since 1)
fgets(3)
is inconsistent
and 2) providing a function to look up an author from a title should
do just that and not require the caller to pass it a title with a \n on
the end of it.
Function declarations and public information for query.c
Your system call wrappers go here.
Function declarations and public information for wrapper.c
.
Once compiled on tiger, you can either use the echo service or
nc -lk
to simulate a server suitable for testing your
application. (The echo service is available on tiger on TCP port 7.)
The assignment says nothing about the specific format of the response text messages. You have to be prepared for anything. Clean up any trailing whitespace that might be part of the response messages and render the result in the manner shown below.
Here is an example of what you will see if you test your application using the echo service (...that we know will simply reply with the string that your client sent to it.)
[winans@tiger]$ ./prog2_client 127.0.0.1 7 Book title: 1985 Author of book: '1985' Book title: 1984 Author of book: '1984' Book title: Hobbit Author of book: 'Hobbit' Book title: Frankenstein Author of book: 'Frankenstein' Book title: ^D [winans@tiger]$
Notice the format and spacing of this example output. Quotes have been added to the response text from the server to clearly show that any trailing whitespace characters have been removed. You are expected to do the same.
Note that prog2_client
allows an optional second command-line
argument to specify a port number. You will want to use it to connect to
a server on another port like nc -l 1234 | hexdump -C
in
order to see the raw data byte values that it sends:
[winans@w520]$ nc -l 1234 | hexdump -C 00000000 48 6f 62 62 69 74 0a |Hobbit.| 00000007
Students in section 1 will implement their server application according to the following usage statement:
Usage: prog2_server <book-database-filename> [<port-number>]
This is different from the assignment handout in that you must provide the name of the book database file on the command line. This allows you to easily create and test your app with different files and/or on your own PC for testing. The default port number shall be 9880.
This is where your server's main()
and usage()
function go. main()
will contain your command line
parsing/processing logic and then call your doServ()
function perhaps like this: doServ(port, argv[1]);
Provides the declaration for the one function in serv.c that is intended to be called from other source files that shall be defined as:
int doServ(uint16_t port, const char *bookdb);
This file shall contain your doServ()
function and the
doLookupBooks()
function discussed below.
int doServ(uint16_t port, const char *bookdb)
This function contains the business logic of the application. Given the port number to listen on and the filename of the book database file, it will bind(), listen() and then accept() client sockets and call doLookupBooks().
static void doLookupBooks(int sock, const char *bookdb)
This function shall contain a loop that will perform the service operation for a single connected client. It will read a plurality of text lines one at-a-time from the client socket. Each text line shall represent one book title. Each line SHOULD be terminated by a single \n character.... however it may have other whitespace caracters at the end like a \r character.
For each text line read from the client, that line shall represent a book title that is searched for in the file given by bookdb, the author extracted and returned to the client as a text line terminated with a single \n character.
The following function is a useful way to extract "A" and "B" from
a string containing "A:B:\n" and place the extracted strings in character arrays
whose names are title
and author
respectively:
fscanf(db, " %[^:]:%[^:]:", title, author)
If you are going to use this method for parsing the book file contents, I recommend that you carefully cut and paste the above line into your code EXACTLY as it is given including every single space character.
Once compiled on tiger, you can either use your client application to test
your server OR you can notice that the protocol described above
is identical to what is sent from the nc
command if it were
connected to your server.
The book database file contents are shown below:
Hobbit:Tolkien: Candide:Voltaire: 1984:Orwell: Frankenstein:Shelly: Introduction to C++:Steve Heller: Making TEX Work:Norman Walsh: Preparing Proposals:Meador: Local Computer Networks:Joseph Hammond and Peter O'Reilly: A First Course in Probability:Sheldon Ross: The Theory of Numbers:Albert Beiler:
If I start the book server and listen on the loopback address port 12345 like this:
[winans@w520 prog2]$ ./prog2_server book.d 12345
... I can then connect to it using nc
and type in
book titles, then it makes sense that it would look like this:
[winans@w520 prog2]$ nc 127.0.0.1 12345 Hobbit <---- I typed this line and pressed enter Tolkien <---- Server responded with this line 12345 <---- I typed this line unknown <---- server response 1985 <---- I typed this line unknown <---- server response 1984 <---- I typed this line Orwell <---- server... Preparing Proposals Meador The Theory of Numbers Albert Beiler Introduction to C++ Steve Heller
Note that some of the book titles have spaces in them.
Assuming that you run your server and client on the same host... here is the same set of book titles entered into my implementation of the client program:
[winans@w520 prog2]$ ./prog2_client 127.0.0.1 12345 Book title: Hobbit Author of book: 'Tolkien' Book title: 12345 Author of book: 'unknown' Book title: 1985 Author of book: 'unknown' Book title: 1984 Author of book: 'Orwell' Book title: Preparing Proposals Author of book: 'Meador' Book title: The Theory of Numbers Author of book: 'Albert Beiler' Book title: Introduction to C++ Author of book: 'Steve Heller' Book title:
Again notice the quote marks are added by the client application to indicate that the author text is properly trimmed before it is printed.
Note also that you SHOULD test your assignment by running your server on lambda.onyuksel.net (99.89.218.77) and client on tiger.cs.niu.edu.
Here is the Makefile that will be used to grade the homework for section 1.
Note that this Makefile will produce a client application executable named
prog2_client
and a server application executable named
prog2_server
In order to use this Makefile, place it in the same directory as your
source files and then type make world
.
To hand in this assignment, execute the following command on tiger:
~courses/bin/mail_prog.631 prog2_client.c wrapper.c wrapper.h in_out.c in_out.h query.c query.h prog2_server.c serv.c serv.h
Last modified: 2018-05-28 11:04:55 CDT
Copyright © 2025 John Winans All rights reserved.