EE450 Socket Programming Project, Fall 2018 Due Date: Thursday Nov 16th, 2018 11:59 PM(Midnight)
(The deadline is the same for all on-campus and DEN off-campus students)
Hard Deadline (Strictly enforced)
The objective of this assignment is to familiarize you with UNIX socket programming. This assignment is worth 10% of your overall grade in this course. It is an individual assignment and no collaborations are allowed. Any cheating will result in an automatic F in the course (not just in the assignment).
If you have any doubts/questions, post your questions on Piazza. You must discuss all project related issues on Piazza. We will give those who actively help others out by answering questions on Piazza up to 10 bonus points to the project.
Problem Statement:
In information theory, the Shannon-Hartley theorem tells the maximum rate at which information can be transmitted over a communications channel of a specified bandwidth in the presence of noise. It is an application of the noisy-channel coding theorem to the archetypal case of a continuous-time analog communications channel subject to Gaussian noise. The theorem establishes Shannon's channel capacity for such a communication link, a bound on the maximum amount of error-free information per time unit that can be transmitted with a specified bandwidth in the presence of the noise interference. The law is named after Claude Shannon and Ralph Hartley. Formulated by:
)1(log2NSBC+=
where
C is the channel capacity in bits per second, a theoretical upper bound on information rate;
B is the bandwidth of the channel in hertz (pass-band bandwidth in case of a band-pass signal);
S is the average signal power over the bandwidth measured in watts (or volts squared);
N is the average noise power over the bandwidth, measured in watts (or volts squared).
In this project, you will implement a model computational offloading where a single client issues three parameters (link ID, file/packet size, and signal power) to the AWS server and expects the reply for the end-to-end delay of the designated link.
The setup of the network is illustrated in Figure 1. The server communicating with the client acts similar as AWS (Amazon Web Server). There are three backend servers, named Back-Server A, Back-Server B and Back-Server C. Back-Servers A and B are storage servers. Each of them possesses a database file, database_a.csv and database_b.csv, respectively, in which attribute values regarding information of links are stored. A toy database is demonstrated in Table 1. There are five attributes in the database, which are {Link ID, Bandwidth, Length, Velocity (Propagation Speed), Noise Power}, from left to right. In database_a.csv and database_b.csv, there will be only five columns of numbers without names of attributes.
The Back-Server C is a computing server. It receives data from the AWS server, performs computational tasks, and returns the results to the AWS server. The monitor connecting to the AWS server is used to record results of every steps and print them out. The client, monitor and the AWS communicate over TCP connections while the AWS and the Back-Servers A, B, & C communicate over UDP connections.
Figure 1. Illustration of the network
The AWS server searches for the information of the designated link (identified by Link ID) over storage servers. After receiving replies from storage servers, the AWS server then sends the link information (bandwidth, link length, propagation velocity, noise power) with client inputs (link ID, file size, signal power) to the computing server. Once the AWS server receives the computed results (which will be end-to-end delay, propagation delay, and transmission delay) from server C, it finally communicates the end-to-end delay to the client in the required format (this is also an example of how a cloud-computing service such Amazon Web Services might speed up a large computation task offloaded by the client).
Table 1. A Toy Database Example
Link ID
Bandwidth (MHz)
Length (Km)
Velocity (107Km/s)
Noise Power (dBm)
3
10
27
15
⋮
25
50
100
75
⋮
3
0.5
10.7
5.6
⋮
20
8
1.2
9.6
⋮
-90
-82
-104
-93
⋮
Source Code Files
Your implementation should include the source code files described below, for each component of the system.
1. AWS: You must name your code file: aws.c or aws.cc or aws.cpp (all small letters). Also you must call the corresponding header file (if you have one; it is not mandatory) aws.h (all small letters).
2. Back-Server A, B and C: You must use one of these names for this piece of code: server#.c or server#.cc or server#.cpp (all small letters except for #). Also you must call the corresponding header file (if you have one; it is not mandatory) server#.h (all small letters, except for #). The “#” character must be replaced by the server identifier (i.e. A or B or C), depending on the server it corresponds to.
Note: You are not allowed to use one executable for all four servers (i.e. a “fork” based implementation).
3. Client: The name of this piece of code must be client.c or client.cc or client.cpp (all small letters) and the header file (if you have one; it is not mandatory) must be called client.h (all small letters).
4. Monitor: The code file for the monitor must be called monitor.c or monitor.cc or monitor.cpp (all small letters) and the header file (if you have one; it is not mandatory) must be called monitor.h (all small letters).
More Detailed Explanations:
Phase 1: (15 points)
All four server programs (AWS -a.k.a. server-D, Back-Server A, B, & C) boot up in this phase. While booting up, the servers must display a boot message on the terminal. The format of the boot message for each server is given in the onscreen message tables at the end of the document. As the boot message indicates, each server must listen on the appropriate port information for incoming packets/connections.
Once the server programs have booted up, the client program is run. The client displays a boot message as indicated in the onscreen messages table. Note that the client code takes an input argument from the command line, that specifies the computation that is to be run and another argument for the desired input value to compute. The format for running the client code is
./client
(Between two inputs, there should be a space)
where , , will be three Integers. For example, a client wants to calculate the end-to-end delay of No.3 link, and the file size is 10K bits and power of signal is -30 dBm.
./client 3 10000 -30
Note that 101000(Watt)(dBm)10log1WattPP= , where P stands for power.
After booting up, the client and monitor establish TCP connections with AWS. After successfully establishing the connection, the client first sends the (, , ) to AWS. Once this is sent, the client should print a message in the format given in the Table 8. This ends Phase 1 and we now proceed to Phase 2.
Phase 2A: (40 points)
In Phase 1, you read the input values from the client and sent them to the AWS server over a TCP connection. Now in phase 2, this AWS server will send selected input value(s) to the 3 back-servers, depending on their functionalities.
The communication between the AWS server and the back-servers happens over UDP. The port numbers used by back-servers A, B and C are specified in Table 3. Since all the servers will run on the same machine in our project, all have the same IP address (the IP address of localhost is usually 127.0.0.1).
Back-end servers A and B are storage servers. Each possesses a database file in which information of links are stored. The AWS server first looks up and requests the link information of the client-specified link from back-end storage servers A and B. After receiving from the AWS server, the storage servers A and B perform the operation {search} (see Table. 2) on their respective databases for an exact match of the given in the Link ID attribute. If the requested link is found, a storage server replies the AWS server a message =1 with link information; otherwise, a storage server replies the AWS server a message =0. The message taking value either ‘1’ or ‘0’ indicates “requested link found” or “requested link not found”, respectively. Note that all messages required to be printed for the AWS server and the storage servers A and B can be found in the format given in the Table 7, 4, and 5, respectively. This ends Phase 2A and we now proceed to Phase 2B.
Phase 2B: (30 points)
Once the AWS server receives replies from both storage servers, the AWS server checks the replied messages. If both messages indicate “requested link not found”, the AWS server sends a result indicating “no match found” to both the monitor and the client. If at least one message indicates “requested link found”, the AWS server sends the with the received link information to the back-end server C. The back-end server C is a computing server. It performs the operation {compute} (see Table. 2) based on the data sent by the AWS server. When the operation is done, the back-end server C will reply all the computed results to the AWS server. All messages required to be printed for the AWS server and the computing server C can be found in the format given in the Table 7 and 6, respectively. This ends Phase 2B and we now proceed to Phase 3.
Table 2. Server Operations
search
In this function, you search for an exact match of the given
in the database. If a match is found, return the link information associated with
compute
In this function, you compute the transmission delay (in ms), the propagation delay (in ms), and the end-to-end delay (in ms) of link based on and the link information associated with
Phase 3: (15 points)
At the end of Phase 2, backend-server C should have the computation results ready. Those results should be sent to the AWS using UDP. When the AWS receives the computation result, it needs to forward the result “end-to-end delay” to the client and all results (all three delays) to the monitor using TCP. The format on how to display the final result is explained in the message table and example outputs below. Please note that there can be a no match result instead of the regular one.
Required Port Number Allocation
The ports to be used by the clients and the servers for the exercise are specified in the following table:
Table 3. Static and Dynamic assignments for TCP and UDP ports
Process
Dynamic Ports
Static Ports
Backend-Server (A)
-
1 UDP, 21000+xxx
Backend-Server (B)
-
1 UDP, 22000+xxx
Backend-Server (C)
-
1 UDP, 23000+xxx
AWS (D)
-
1 UDP, 24000+xxx
1 TCP with client, 25000+xxx
1 TCP with monitor, 26000+xxx
Client
1 TCP
Monitor
1 TCP
NOTE: xxx is the last 3 digits of your USC ID. For example, if the last 3 digits of your USC ID are “319”, you should use the port: 21000+319 = 21319 for the Backend-Server (A). It is NOT going to be 21000319.
ON SCREEN MESSAGES:
Table 4. Backend-Server A on screen messages
Event
On Screen Message (inside quotes)
Booting up (Only while starting):
“The Server A is up and running using UDP on port .”
Upon receiving the input link ID:
“The Server A received input ”
After searching:
“The server A has found match” (m = 0 or 1)
After sending the results to the AWS server (D):
“The Server A finished sending the output to AWS”
ON SCREEN MESSAGES:
Table 5. Backend-Server B on screen messages
Event
On Screen Message (inside quotes)
Booting up (Only while starting):
“The Server B is up and running using UDP on port .”
Upon receiving the input link ID:
“The Server B received input ”
After searching:
“The server B has found match” (m = 0 or 1)
After sending the results to the AWS server (D):
“The Server B finished sending the output to AWS”
ON SCREEN MESSAGES:
Table 6. Backend-Server C on screen messages
Event
On Screen Message (inside quotes)
Booting up (Only while starting):
“The Server C is up and running using UDP on port .”
Upon receiving the input:
“The Server C received link information of link , file size , and signal power ”
After calculating:
“The server C finished the calculation for link ”
After sending the results to the AWS server (D):
“The Server C finished sending the output to AWS”
ON SCREEN MESSAGES:
Table 7. AWS on screen messages
Event
On Screen Message (inside quotes)
Booting up (only while starting):
“The AWS is up and running.”
Upon Receiving the input from the client:
“The AWS received link ID=, size=, and power= from the client using TCP over port ”
After sending the input to the monitor:
“The AWS sent link ID=, size=, and power= to the monitor using TCP over port ”
After querying backend-server A, B:
“The AWS sent link ID= to Backend-Server using UDP over port ”
(i = A, B)
After receiving result from backend-server A, B:
“The AWS received matches from Backend-Server using UDP over port ”
(m = 0, 1 i = A, B)
After querying backend-server C:
“The AWS sent link ID=, size=, power=, and link information to Backend-Server C using UDP over port ”
After receiving result from backend-server C:
“The AWS received outputs from Backend-Server C using UDP over port ”
After sending the result to the client:
“The AWS sent delay=ms to the client using TCP over port ”
After sending the final result to the monitor:
“The AWS sent detailed results to the monitor using TCP over port ”
After sending result to monitor and client If no result is returned by server A, B:
“The AWS sent No Match to the monitor and the client using TCP over ports and , respectively”