We're going to write a multi-threaded file server, and a multi-threaded client program. This will be done in two parts:
jserver host port file verboseJserver serves a socket on the specified host and port. It then opens the specified file, and reads all of it into a buffer in memory. It then accepts client connections. Each time a client connects, it creates a thread to handle it. The goal of the client/server interaction is for the server to send the client a portion of the file over the connection. Verbose should be either yes or no. If no, then jserver should run silently, with no output. If yes, it should print messages that are specified below.
Clients talk to the server by sending it three integers, in text form, separated by either white space or newlines. The integers are:
When the server receives these three integers, it sends to the client Size bytes of the file, starting at byte Sbyte. It does this with potentially multiple write() calls, where the number of bytes in the write() calls is Blocksize.
So, for example, look at the input file in input.txt:
AAAAA BBBBB CCCCC DDDDD EEEEE FFFFFNow, suppose I run jserver on port 8888 of cetus4.cs.utk.edu. I can attach to that server from any machine on the internet using telnet. Here are some examples (the input is in bold):
UNIX> telnet cetus4.cs.utk.edu 8888
Trying 160.36.56.86...
Connected to cetus4.cs.utk.edu.
Escape character is '^]'.
0 12 12
AAAAA
BBBBB
Connection closed by foreign host.
UNIX> telnet cetus4.cs.utk.edu 8888
Trying 160.36.56.86...
Connected to cetus4.cs.utk.edu.
Escape character is '^]'.
0
12 6
AAAAA
BBBBB
Connection closed by foreign host.
UNIX> telnet cetus4.cs.utk.edu 8888
Trying 160.36.56.86...
Connected to cetus4.cs.utk.edu.
Escape character is '^]'.
10 12 1
B
CCCCC
DDDDConnection closed by foreign host.
UNIX> telnet cetus4.cs.utk.edu 8888
Trying 160.36.56.86...
Connected to cetus4.cs.utk.edu.
Escape character is '^]'.
0 10000 5000
AAAAA
BBBBB
CCCCC
DDDDD
EEEEE
FFFFF
Connection closed by foreign host.
UNIX> telnet cetus4.cs.utk.edu 8888
Trying 160.36.56.86...
Connected to cetus4.cs.utk.edu.
Escape character is '^]'.
40 10 10
Connection closed by foreign host.
UNIX> telnet cetus4.cs.utk.edu 8888
telnet cetus4.cs.utk.edu 9888
Trying 160.36.56.86...
Connected to cetus4.cs.utk.edu.
Escape character is '^]'.
0 (Then a CNTL-D)
Connection closed by foreign host.
UNIX> telnet cetus4.cs.utk.edu 8888
Trying 160.36.56.86...
Connected to cetus4.cs.utk.edu.
Escape character is '^]'.
0 12 20
AAAAA
BBBBB
Connection closed by foreign host.
UNIX> telnet cetus4.cs.utk.edu 8888
Trying 160.36.56.86...
Connected to cetus4.cs.utk.edu.
Escape character is '^]'.
0 Yick 60
Connection closed by foreign host.
UNIX> telnet cetus4.cs.utk.edu 8888
Trying 160.36.56.86...
Connected to cetus4.cs.utk.edu.
Escape character is '^]'.
-1 20 30
Connection closed by foreign host.
UNIX>
Note a few things. First, if bad input is given (e.g. an unreasonable starting
byte, a non-integer, the connection closes before all three integers are given),
the server simply closes the connection, and continues serving.
Otherwise, if the client specifies any legal portion of the file, it is
sent. If the client specifies a region that is too big (such as 0 40 40), then
the server only sends the legal bytes from that region (in this example, 36
bytes starting from byte 0). The point of the blocksize is to control
the size of the write() call. If blocksize is bigger than
size, then obviously, it should be truncated so that it is equal to
size.
If verbose is yes, then the server should print out the following messages:
A little help: Use fdopen and fscanf() for reading from the client. Do not use fdopen or any standard I/O calls for writing bytes to the client.
This code does not need any synchronization primitives. Ask yourself why (you don't need to answer this for the lab, just for your own edification).
After creating a thread, call pthread_detach() on it. Again, ask yourself why.
Don't worry about SIGPIPE.
jclient host port nthreads filesize chunksize blocksize verboseThis client will first allocate a buffer of size filesize. It then creates nthreads threads. Each thread will go through the following activities:
When all threads have exited, the file from the server (or part of it if filesize is less than the server's file size) should be in the buffer. Jclient writes this to standard output and exits.
Some notes:
If verbose is no, the client should act silently. If verbose is yes, the client should print the following messages:
Test my code if you have any questions on how things should work. A few huge input files are in the lab directory:
For interest -- check out the performance of running multiple threads from one client to one server with these huge files. When you take Networking, ask the instructor whether what you did is considered "TCP Friendly."