Multithreaded Traffic Throttling Web Server in C/C++
多线程代写/web代写/C++代写/C代写/socket代写: 这是一个典型的通过C C++进行多线程web服务器程序模拟的项目,主要通过多线程进行网络通信的实现
Background
(Please check out the PA4 FAQ before sending your questions to the TAs, the course producers, or the instructor.)
We will start with you PA2 web server and add some additional functionalities to it. (1) We will make it multithreaded so that it can accept multiple requests from multiple web browsers simultaneously. (2) Our new web server will throttle each connection so that it has a maximum long-term throughput and a maximum short-term burst size. These two parameters will be controlled from a configuration file your server will read. (3) Our web server will have a console where a user can input commands such as controlling the parameters for throttling and shutting down the web server.
Electronic submissions only.
Compiling
You must use a Makefile so that when the grader simply enters:
make pa4
(or simply “make”), an executable named pa4 is created. Please make sure that your submission conforms to the general compilation requirements and README requirements.
The grader will be using the above command to create your executable on nunki.usc.edu or on a Ubuntu 14.04 or 16.04 machine running inside VMware/VirtualBox/VagrantBox as mentioned in the general compilation requirements.
Commandline Syntax
The commandline syntax (also known as “usage information”) for pa4 is as follows:
pa4 configfile
A configfile is a configuration file that contains all the information your server needs in order to run. It contains information such as port number, server root directory, connection throttling parameters, etc.
Multithreading
You are required to create one thread to interact with the user and one networking thread each to handle each client connection. Within each networking thread, you must throttle the connection according the throttling requirements.
You must assign each active connection a unique connection number, starting with 1 and sequentially afterwards. The highest connection number you can assign is 999,999. Afterwards, you should start from 1 again, but you must make sure that you do not assign a connection number that’s already in use.
Your web server must shutdown gracefully, i.e., when it’s time to shutdown, you must ask all the running threads to self-terminate. You must make sure that your main thread will not self-terminate until all the other threads have terminated.
If you want to use Boost C++ on Ubuntu 14.04 or 16.04 to do multithreading, you can find some Boost Thread documentation here. The Boost version on nunki.usc.edu is quite out-dated. If you have to use nunki, you can use standard C++ threads in C++11 (in “/usr/usc/gnu/gcc/5.2.0”). You can find some C++11 thread documentation here.
If you are using C, you can use POSIX threads (i.e., “pthread”) for multithreading. You can find some POSIX thread documentation here.
Throttling Data Sending / Traffic Shaping
Throttling the sending rate of out-going data is also known as “traffic shaping”. The goal is to make sure that the out-going traffic (i.e., data rate) conforms to a certain traffic profile. For this assignment, you must control the maximum long-term throughput and a maximum short-term burst size that’s sent to the client by using a mechanism called Token Bucket Filter to control the data sending characteristics of our server.
Figure 1
Figure 1: Token Bucket Filter.
Figure 1 above depicts a token bucket filter. It has three parameters: r is the token rate, B is the bucket depth, and P is the token requirement per packet. Tokens arrives into the bucket at the rate of r tokens per second. If the bucket has B tokens in it when a token arrives, the token is lost.
Conceptually, our message (application-level data) is divided into “packets”, 1,024 bytes each (only the last packet can be less than 1,024 bytes long). We will refer to 1,024 bytes as 1 KB from this point on (even though “KB” stands for “kilo-bytes” and a “kilo” is 1,000 in the metric system). All these packets are put into Q1 initially and no more packets can arrive. They are not eligible for transmission until they are placed into Q2. The packet at the head of Q1 can only be moved into Q2 if there are at least P tokens in the bucket. If there are P tokens or more in the bucket, the packet at the head of Q1 is immediately removed into Q2 and P tokens are removed from the bucket. If there are less than P tokens in the bucket, you must wait for more tokens to get deposited into the bucket. Clearly, P must be ≤ B or no packet will ever appear in Q2.
With this setup, the maximum short-term burst size is B/P KB and the maximum long-term throughput is r/P KB/sec.
From the description above, it looks like there are two concurrent activities. One is the token depositing activity and one is the data transmission activity. For this assignment, you can implement these activities using only one thread as follows.
(1) When you are ready to send data to the client, you initialize the token bucket filter data structure. Since you can send out 1 KB immediately, you must initialize the bucket to have P tokens.
(2) You should read the clock and save its value. This is the start time of your transmission. The idea here is that a token should arrive once ever 1/r seconds. You don’t have to use another thread to drop tokens into the bucket. You just have to figure things out by doing some calculation with clock values!
(3) If there are P or more tokens in the bucket, remove P tokens and write 1 KB to the socket and wait for the write operation to be completed.
(4) When writing to the socket is done, you need to figure out how many tokens has arrived while you were writing. Then you calculate how many tokens must have been placed in the bucket during this time period.
(5) If there are P or more tokens in the bucket, you can go back to step (3) and continue.
(6) If there are not enough tokens, you need to figure out when you will have exactly P tokens in the token bucket. Let’s call that time X. Then you have your thread go to sleep and schedule it to wake up at the time X. When your thread wakes up, you need to figure out how many tokens have actually arrived while you were sleeping (since your thread can wake up at some time after X and not exactly at time X). Then you set the token bucket to have the correct number of tokens and go back to step (3) and continue.
(7) When all data are sent, your thread can self-terminate.
To figure out the state of the bucket, you can do the following. The state of the bucket has two pieces of information. It stores the timestamp of when the last token arrived. Let’s call this t1. It also stored the number of tokens in the bucket immediately before the thread writes to the socket (but after P tokens have been removed from the token bucket). Let’s call this b1. The state of the bucket is (t1,b1). Initially, t1 is the start time and b1 is zero and your thread will write 1 KB to the socket.
After your thread has returned from writing to the socket (or from sleeping if it did not have enough tokens) and immediately before it can write to the socket, it needs to check if there are enough tokens in the bucket. At this time, it has to figure out exactly how many tokens are in the token bucket. How’s how it can be done. It reads the clock and get the current time, let’s call it t2. Then n = (int)(r×(t2-t1)) is the number of tokens that has arrived since t1. There are 3 cases you have to consider (depending on the value of b1+n):
Case1: If b1+n ≥ B, then you conclude that at time t2, the token bucket is full. Since P tokens will be removed to send the next KB of data, when the thread is about to write to the socket the next time, the state of the bucket will be (t1+n/r,B-P).
Case2: If b1+n < P at time t2, there are not enough tokens to transmit. Your thread will sleep until t1+(P-b1)/r. At the time your thread goes to sleep, the state of the bucket will be (t1+n/r,b1+n). Case3: If b1+n ≥ P at time t2, P tokens will be removed to send the next KB of data, when the thread is about to write to the socket the next time, the state of the bucket will be (t1+n/r,b1+n-P). Figure 2 below demonstrates the calculation above. The greyed part of the Figure represents conceptually what must have happened when our thread sleeps. Figure 2 Figure 2: Token Bucket State. At the time your thread writes to the socket, the state of the bucket was (t1,b1) (estabelished when the last token arrived). The thread wakes up later and at time t2, it’s ready to write to the socket again. Now it has to figure out exactly how many tokens are in the bocket. In this example, we have n = (int)(r×(t2-t1)) = 3. We also know that the last token has arrived at time t1+n×(1/r) = t1+3/r and the token bucket has min(B,b1+3) tokens. If this number is ≥ P, the thread will remove P tokens and write the next 1 KB of data into the connection. Otherwise, the thread needs to sleep for t1+(P-b1)/r-t2 seconds. [BC: paragraph added 2/15/2018] For this assignment, accuracy is important! Please use wget or lynx to connect to your server and observe the download speed for a reasonably-sized file. If a token bucket is installed for a particular download, as mentioned above, the long-term throughput is suppose to be r/P KB/sec. You need to run wget or lynx for a little bit to wait for the download speed to settle. Your accuracy must be within ±10% of r/P KB/sec. User Console Your web server will have an interactive commandline interface. Your program must use “> ” (i.e., a “greater than” symbol followed by a space) as the command prompt to tell that user that you are expecting the user to enter a line of command.
The commands and their meanings are:
Name Arguments Description
info # List the following information for the specified connection (please ignore additional arguments if they are present):
[#]\tClient connecting from IP:PORT\n
\tContent-Type: TYPE/SUBTYPE\n
\tContent-Length: LENGTH\n
\tContent-MD5: MD5HEXVALUE\n
\tStart-Time: TIMESTAMP\n
\tShaper-Params: B=???, P=???, MAXR=???/s, DIAL=???%, r=??? KB/s\n
\tSent: BC of CL (P%) downloaded at TP, time elapsed: ET\n
where # is the connection number, TYPE/SUBTYPE is the MIME Type in the corresponding response header, LENGTH is the size of corresponding response content (in bytes), MD5HEXVALUE is the MD5 message digest of the response content, r is the current token rate (i.e., MAXR*percent/100), BC is the Byte Count (i.e., number of data bytes written into the connection), CL is the Content Length, P is the Percent data sent, ET is the Elapsed Time, and TP is the average data sending rate (i.e., BC/ET). If ET is zero, please give a TP of 0. Please make sure you display each value with a corresponding unit so it’s clear to the user what the values mean.
The Shaper-Params line should only be present if a traffic shaper is installed for this connection.
If # is an invalid connection number, you must print the following and continue:
No such connection: #\n
In case you are processing the request for this connection and do not have all the information above, you should print the following:
[#]\tClient connecting from IP:PORT (in preparation)\n
status List all the active connection information. (Please ignore arguments if they are present.)
You must print the connection information in the order of increasing connection number.
If there are no active connection, you must print:
No active connection\n
dial # percent Set the dial of the specified connection number (i.e., #) to percent (thus set r = MAXR*percent/100). (Please ignore additional arguments if they are present.)
If # is an invalid connection number, you must print the following and continue:
No such connection: #\n
If this connection is still in preparation, you must print the following and continue:
Cannot set dial, connection # is in preparation\n
If no token bucket filter is instaled for this connection, you must print the following and continue:
Connection # has no token bucket filter installed\n
[BC: fixed 2/18/2018] If percent is < 1 or > 100, you must print the following and continue:
Dial value is out of range (it must be >=1 and <= 100)\n
If the token rate has been changed as a result of this command, you must print:
Dial for connection # changed to ???%. Token rate now at ??? KB/s\n
where the first ??? is new dial setting and the 2nd ??? is the new token rate. If there is no change to the token rate, you must print:
Token rate for connection # unchanged\n
close # Shutdown and close the socket for the specified connection number (i.e., #) and remove this connection from the list of active connections. (Please ignore additional arguments if they are present.)
If # is an invalid connection number, you must print the following and continue:
No such connection: #\n
After the connection is closed, you must print the following:
Connection # is closed\n
quit Exit your program gracefully. (Please ignore arguments if they are present.)
You must cancel each child thread that’s handling a connection. When such a child thread is being canceled, it should shutdown the socket, close the socket, then self-terminate. When a child thread has terminated, you must print the following:
Connection # is closed\n
After all the child thread have terminated, your console thread must print the following message and then self-terminate:
Console thread terminated\n
When your console thread is dead, your main thread can exit.
Please note that in Unix, you can create the end-of-input condition (also known as the EOF condition) in stdin by typing the <Cntrl+d> character (i.e., hold down the key and type d). If your program encouters the end-of-input condition in stdin, you must treat it as if the quit command has been enters and exit your program gracefully.
If the command name is not one of the above, you must print:
Command not recognized. Valid commands are:\n
\tinfo #\n
\tstatus\n
\tdial # percent\n
\tclose #\n
\tquit\n
If a particular command is malformed (such as wrong number of arguments), please give the correct usage information for that command.
Reading Client Requests
This part is identical to PA2.
Normal Response
This part is identical to PA2.
Responding With Error Codes
This part is identical to PA2.
Logging
This part is almost the same as PA2. There are two main differences. First, since multiple clients can connect simultaneously, the log messages can interleave. Therefore, other than the first three lines, every line of text you are logging, you must prepend a connection number. For example, in PA2, you were suppose to log the following information:
\n
Client connecting from IP:PORT\n
For this assignment, you must use:
\n
[#] Client connecting from IP:PORT\n
where “#” denotes a connection number you have assigned to this session with the client. Also, unlike the case in console printout, there is no tab character after the connection number. Connection numbers must start with 1 when your server gets started and you should never reuse a connection number until you get past 999,999. You must make sure that all active connections have different connection numbers.
Similarly, anything you log in PA2 that begins with a tab character, you must add connection information to it immediately after the tab character. For example, if this is what you wrote into the log file in PA2:
Server listening at 68.181.201.3:12000\n
Server root at ‘/home/scf-22/csci551b/public/cs353/pa2/data’\n
\n
Client connecting from 68.181.201.3:35859\n
GET /images.html HTTP/1.0\r\n
Host: 68.181.201.3:12000\r\n
Accept: text/html, text/plain, text/sgml, */*;q=0.01\r\n
Accept-Encoding: gzip, compress, bzip2\r\n
Accept-Language: en\r\n
User-Agent: Lynx/2.8.6dev.14 libwww-FM/2.14\r\n
\r\n
Request file: ‘images.html’\n
Content-Type: text/html\n
Content-Length: 854\n
Content-MD5: b54146539dfce7adc523f4e3a18519b4\n
(DONE)\n
For this assignment, it should look like the following (assuming this is connection #1):
Server listening at 68.181.201.3:12000\n
Server root at ‘/home/scf-22/csci551b/public/cs353/pa2/data’\n
\n
[1] Client connecting from 68.181.201.3:35859\n
[1] GET /images.html HTTP/1.0\r\n
[1] Host: 68.181.201.3:12000\r\n
[1] Accept: text/html, text/plain, text/sgml, */*;q=0.01\r\n
[1] Accept-Encoding: gzip, compress, bzip2\r\n
[1] Accept-Language: en\r\n
[1] User-Agent: Lynx/2.8.6dev.14 libwww-FM/2.14\r\n
[1] \r\n
[1] Request file: ‘images.html’\n
[1] Content-Type: text/html\n
[1] Content-Length: 854\n
[1] Content-MD5: b54146539dfce7adc523f4e3a18519b4\n
[1] [Date: Sun Feb 18 2018 22:27:23.102746] (DONE)\n
The second difference is that if you are going to return a normal response and if you have a traffic-shaper installed for the corresponding MIME Type, you must print the following into the log file (the 4th line is new for this assignment):
\t[#] Content-Type: TYPE/SUBTYPE\n
\t[#] Content-Length: LENGTH\n
\t[#] Content-MD5: MD5HEXVALUE\n
\t[#] [Date: TIMESTAMP] Shaper-Params: B=???, P=???, MAXR=???/s, DIAL=???%, r=??? KB/s\n
where “#” is a connection number, TYPE/SUBTYPE is the MIME Type you will send in the response header, LENGTH is the size of response content (in bytes), MD5HEXVALUE is the MD5 message digest of the response content, “???” represents the actual throttling parameter values, and “TIMESTAMP” is the current time in the same format as PA3. The value of r is a floating point number, you must print its value with at least 4 significant digits (i.e., if you are using printf(), you can use “%.4g” to get the correct precision). If no traffic-shaper needs to be installed, you must not print the line that contains the Shaper-Params.
If any of the throttling parameter values changed when you are sending back a response, you must append a new line of throttling parameter values to the log file as following:
\t[#] [Date: TIMESTAMP] Shaper-Params: B=???, P=???, MAXR=???/s, DIAL=???%, r=??? KB/s\n
where “???” represents the updated throttling parameter values and “TIMESTAMP” is the current time. After you have sent all the response data to the client, you must append the following line to the log file:
\t[#] [Date: TIMESTAMP] (DONE)\n
where “TIMESTAMP” is the current time. If the user terminated a connection before all the response data is sent, you must append the following line to the log file:
\t[#] [Date: TIMESTAMP] (TERMINATED BY USER)\n
PID File
This part is almost identical to PA2. The only difference is that there is no default PID file name.
MIME Types File Format
This part is identical to PA2.
Configuration File Format
The configuration file you must use will be in the Windows INI File Format. Below is an example of a configuration file that you would use with this assignment:
[config]
port=12000
log=pa4.log
pid=pa4.pid
root=./data
mime=mime.types
[text/html]
B=3
P=1
MAXR=10
DIAL=25
A Windows INI file may contain multiple sections. A section name is enclosed in a pair of square brackets. In the above example, there is a “config” section and a “text/html” section. Within a section, we can have arbitrary number of lines, each of which is a key=value pair. There are considered property names and property values for the corresponding section. There is no explicit “end of section” delimiter. Sections end at the next section declaration, or the end of the file. Sections may not be nested. If the first character of a line is a semicolon, the line is a comment and must be ignored. If a line only contains space or tab characters, it must be ignored.
There are various rules for determining if an INI file is valid or not. For this assignment, we will use the following rules (to make parsing easier):
(a) There must be no space or tab characters in the section name line.
(b) There must be no space or tab characters in a key=value line.
(c) Section names are case insensitive and there cannot be two sections with identical names.
(d) Within each section, keys (or property namaes) are case insensitive and there cannot be two identical keys (or property names).
You can trust that the configuration file we will use for grading satisfied (a) and (b) above. In addition, all section names will be in lower case, all keys in the [config] section (if present) will be in lower case and all keys in the other sections will be in upper case and all section names and keys will be spelled correctly. (You still have to check to make sure that the values are present, correct, and meaningful, but you can assume that they are all formatted properly if they are present.)
A “config” section is required and it must have exactly the following 5 key=value lines (can come in any order):
port=number – number is the port number your server must listen on.
log=logfilename – logfilename is the file name for logging server messages.
pid=pidfilename – pidfilename is the file name for storing the process ID of your server.
root=directory – directory is the root directory of your web server.
mime=mimetypesfile – mimetypesfile is the MIME Type file your server must use.
The section names for all other sections of the configuration INI file are MIME Types (i.e., it has the format of type/subtype). In each of these sections, there are exactly 4 key=value lines (can come in any order):
B=number – number is the bucket depth. It must be an integer ≥ 1 and ≤ 10.
P=number – number is the number of tokens required before 1 KB of data is allowed to be released for transmission. It must be an integer ≥ 1 and ≤ B.
MAXR=max_rate – max_rate is token arrival rate (per second) if the dial is set a 100%. It must be an integer ≥ 1 and ≤ 1,000.
DIAL=percent – percent is a percentage value to be used such that the initial token arrival rate r = MAXR*percent/100. It must be an integer ≥ 1 and ≤ 100.
The HTTP header you sent to the client contains the Content-Type of the data that you will send. You must use the Content-Type information to check if you need to install a Token Bucket Filter when you are sending the data. You must match the Content-Type with the section name of the configuration file. If there is a match, you must install a Token Bucket Filter and initialize it with the parameters in that section of the configuration file then throttle the data according to the rules of the Token Bucket Filter. If you cannot find a match, you must send the data without throttling.
A sample configuration file is provided as “pa4.config” here.
Input and Output Examples
Let’s say that you run the following command in one Terminal window on nunki.usc.edu:
set srcdir=~csci551b/public/cs353/pa4
set pa2dir=~csci551b/public/cs353/pa2
./pa4 $srcdir/pa4.config
A copy of the $pa2dir/mime.types file on nunki is available as “mime.types” here. A copy of the $srcdir/pa4.config file on nunki is available as “pa4.config” here.
In a separate window, you should ssh to nunki.usc.edu, cd into the directory where you ran the above command, and do:
tail -f pa4.log
At this point, you should see 3 lines at the beginning of pa4.log:
Server listening at 68.181.201.3:12000\n
Server root at ‘/home/scf-22/csci551b/public/cs353/pa2/data’\n
Please note that the 3rd line is a blank line. The first line says that your web server is listening on port 12000 at IP address 68.181.201.3. Therefore, you should be able use lynx to connect to your web serving using the following command (in a separate Terminal window on nunki.usc.edu):
lynx http://68.181.201.3:12000/images.html
If lynx can connect to your web server successfully, you should see that lynx will display a text version /home/scf-22/csci551b/public/cs353/pa2/data/images.html. You should also see that in the 2nd window, the following lines got added to pa4.log:
[BC: fixed (added connection number) 2/26/2018]
[1] Client connecting from 68.181.201.3:35859\n
[1] GET /images.html HTTP/1.0\r\n
[1] Host: 68.181.201.3:12000\r\n
[1] Accept: text/html, text/plain, text/sgml, */*;q=0.01\r\n
[1] Accept-Encoding: gzip, compress, bzip2\r\n
[1] Accept-Language: en\r\n
[1] User-Agent: Lynx/2.8.6dev.14 libwww-FM/2.14\r\n
[1] \r\n
[1] Request file: ‘images.html’\n
[1] Content-Type: text/html\n
[1] Content-Length: 854\n
[1] Content-MD5: b54146539dfce7adc523f4e3a18519b4\n
[1] (DONE)\n
All but the first line is indented by a tab character (including the blank-looking line). Please understand that if you are just looking at the output of the tail command in the 2nd window, you will not see any of the ‘\r’ and ‘\n’ characters. Please compare the above information with the Logging section of this spec to understand all the formatting requirement of all these lines.
Type q (followed by y) in the lynx window to quit lynx. Then press <Cntrl+C> (i.e., hold-down the key and type c) in the first window to terminate your web server. The resulting pa4.log is provided here.
To verify that the Content-Length line has the following value, you can run the following command on nunki.usc.edu in the first window:
ls -l $srcdir/data/images.html
and you should see:
-r–r–r– 1 csci551b 854 Jan 14 15:07 /home/scf-22/csci551b/public/cs353/pa2/data/images.html
The 854 there is the size of the file.
To verify that the Content-MD5 line has the following value, you can run the following command on nunki.usc.edu in the first window:
openssl md5 $srcdir/data/images.html
Grading Guidelines
The grading guidelines has been made available. Please understand that the grading guidelines is part of the spec and the grader will stick to it when grading. It is possible that there are bugs in the guidelines. If you find bugs, please let the instructor know as soon as possible.
The grading guidelines is the only grading procedure we will use to grade your program and the grader must grade your submission on nunki.usc.edu or on a Ubuntu 14.04 or 16.04 machine running inside VMware/VirtualBox/VagrantBox. No other grading procedure will be used. If your program only runs on some other platform, you will get no credit for it. Therefore, it’s imperative that you run your code through the grading guidelines on nunki.usc.edu or on a Ubuntu 14.04 or 16.04 machine running inside VMware/VirtualBox/VagrantBox. To the best of our effort, we will only change the testing data (including file names and commandline arguments) for grading but not the commands. (We may make minor changes if we discover bugs in the script or things that we forgot to test.)
Miscellaneous Requirements and Hints
Please take this spec and the grading guidelines very seriously. Please understand that graders must follow the grading guidelines when grading and they are not permitted to use a different grading procedure to grade your submission (due to our fairness policy). Please understand that you won’t get credit for simply coding, i.e., we cannot give you any partial credit for your “effort”. We can also give you credit for “results”. It is also imperative that you test your code against the grading guidelines on nunki.usc.edu or on a Ubuntu 14.04 or 16.04 machine running inside VMware/VirtualBox/VagrantBox. If your code runs perfectly on some other platform, it cannot be considered for grading.
Please read the programming FAQ if you need a refresher on C/C++ file I/O and bit/byte manipulications.
[BC: typo fixed 2/13/2018] You must not look at, copy, or share any code fragments from your classmates or previous semesters to implement this assignment.
It’s important that every byte of your data is read and written correctly. You will lose a lot of points if one byte of data is generated incorrectly! The grading of this assignment will be harsh and you must make your code to work according to the posted grading guidelines.
If you are programming in C, I/O functions such as fgets(), scanf(), and printf() are really meant for inputing/outputing ASCII strings. Do not use them to input/output binary data!
The Solaris workstations in the ITS lab in SAL have the same setup as nunki.usc.edu. So, if you are logged on to one of these workstations, please do your development locally and not to overload nunki unnecessarily.
Start working on this early! This assignment is tedious and it would take quite a bit of time to get it done correctly.
Submission
All assignments are to be submitted electronically – including your README file. To submit your work, you must first tar all the files you want to submit into a tarball and gzip it to create a gzipped tarfile named pa4.tar.gz. Then you upload pa4.tar.gz to the Bistro system. On nunki.usc.edu or aludra.usc.edu, the command you can use to create a gzipped tarfile is:
/usr/usc/bin/gtar cvzf pa4.tar.gz MYLISTOFFILES
(On Ubuntu Linux, please replace /usr/usc/bin/gtar with tar.) Where MYLISTOFFILES is a list of file names that you are submitting (you can also use wildcard characters if you are sure that it will pick up only the right files). DO NOT submit your compiled code, just your source code and README file. Two point will be deducted for each binary file (e.g., pa4, .o, .gch, core, etc.) in your submission.
Please note that the 2nd commandline argument of the gtar command above is the output filename of the gtar command. So, if you omit pa4.tar.gz above, you may accidentally replace one of your files with the output of the gtar command. So, please make sure that the first commandline argument is cvzf and the 2nd commandline argument is pa4.tar.gz.
A pa4-README.txt template file is provided here. You must save it as your pa4-README.txt file and follow the instructions in it to fill it out with appropriate information and include it in your submission. Please make sure that you satisfy all the README requirements.
Here are a couple of sample commands for creating your pa4.tar.gz file (your command will vary depending on what files you want to submit):
/usr/usc/bin/gtar cvzf pa4.tar.gz *.c *.h pa4-README.txt
/usr/usc/bin/gtar cvzf pa4.tar.gz *.cpp *.h pa4-README.txt
You should read the output of the above commands carefully to make sure that pa4.tar.gz is created properly. If you don’t understand the output of the above commands, you need to learn how to read it! It’s your responsibility to ensure that pa4.tar.gz is created properly.
You need to run bsubmit to submit pa4.tar.gz to the submission server. Please use the following command:
~csci551b/bin/bsubmit upload \
-email `whoami`@usc.edu \
-event merlot.usc.edu_80_1372906710_184 \
-file pa4.tar.gz
If the command is executed successfully, the output should look like the sample mentioned in the submission web page. If it doesn’t look like that, please fix your command and rerun it until it looks right. If there are problems, please contact the instructor.
It is extreme important that you also verify your submission after you have submitted pa4.tar.gz electronically to make sure that every you have submitted is everything you wanted us to grade.
Finally, please be familiar with the Electronic Submission Guidelines and information on the bsubmit web page.
[Last updated Sat Mar 31 2018] [Please see copyright regarding copying.]