和往年作业一样,开发五个Server/Client,然后实现一个Web注册系统。
![Network](https://i1.wp.com/refugeictsolution.com.ng/wp-
content/uploads/2021/05/client-server.png)
Objective
The objective of this assignment is to familiarize you with UNIX socket
programming. 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 D2L. You
must discuss all project related issues on the Piazza discussion forum. We
will give those who actively help others out by answering questions on the
Piazza discussion forum up to 10 bonus points.
Problem Statement
Web registration system has been a critical system for USC students. It is the
key place for students to plan their future course of study and plays an
important role in students’ academic success. Imagine that one day the web
registration system is gone and tens of thousands of students are left unknown
about what to choose for the next semester. A course might be over-crowded
with hundreds of students because students don’t know how many students have
already registered and the administrator might have to randomly select
hundreds of people to drop from that course. Or you can imagine on the first
day of the semester, the web registration system is suddenly down, all
students are anxiously refreshing their webpage. And another thing to consider
is the security, keep in mind that our web registration system should have a
kind of authorization, for example username and password. Otherwise, it will
be a popular hoax among students to drop courses for others. Thus a secure,
reliable, functional and informative web registration system is vital for our
school. As a networking course, we will try to approach this problem with some
simplification. We will make the assumption that only one student will access
the web registration system each time, and there are only two departments of
courses to choose from. We will also introduce a very simple authorization
schema.
In this project, you will implement a simple web registration system for USC.
Specifically, a student will use the client to access the central web
registration server, which will forward their requests to the department
servers in each department. For each department, the department server will
store the information of the courses offered in this department. Additionally,
a credential server will be used to verify the identity of the student.
There are total 5 communication end-points:
- Client: used by a student to access the registration system.
- Main server (serverM): coordinate with the backend servers.
- Credential server (serverC): verify the identity of the student.
- Department server(s) (serverCS and serverEE)): store the information of courses offered by this department.
For the backend servers, Credential server and Department servers will access
corresponding files on disk, and respond to the request from the main server
based on the file content. It is important to note that only the corresponding
server should access the file. It is prohibited to access a file in the main
server or other servers. We will use both TCP and UDP connections. However, we
assume that all the UDP packages will be received without any error.
Source Code Files
Your implementation should include the source code files described below, for
each component of the system.
- ServerM (Main Server): You must name your code file: serverM.c or serverM.cc or serverM.cpp (all small letters except ‘M’). Also you must include the corresponding header file (if you have one; it is not mandatory) serverM.h (all small letters except ‘M’).
- Backend-Servers C, CS and EE: 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 include 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. C or CS or EE), depending on the server it corresponds to. (e.g., serverC.cpp, serverEE.cpp & serverCS.cpp)
Note: You are not allowed to use one executable for all four servers (i.e. a
“fork” based implementation). - 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).
Input Files
There are three input files that are given to the credential Server and two
department servers and should be read by the server when it is up and running.
- cred.txt: contains encrypted usernames and passwords. This file should only be accessed by the Credential server.
- ee.txt: contains course information categorized in course code, credit, professor, days and course name. Different categories are separated by a comma. There could be space(s) or semicolons, except commas, in a category. One example is given below. This file should only be accessed by the EE Department server.
- cs.txt: Same format as ee.txt. This file should only be accessed by the CS Department server.
Note: cred_unencrypted.txt is the unencrypted version of cred.txt, which is
provided for your reference to enter a valid username and password. It should
NOT be touched by any servers!!!
Application Workflow Phase Description
Phase 0
Please refer to the Process Flow section to start the main server, Credential
server, EE
Department server, CS Department server and Client in order. Upon three
backend servers (Credential server, CS Department server and EE Department
server) are up and running, each backend server should read the corresponding
file and store the information in a certain data structure. You can choose any
data structure that accommodates the needs.
Phase 1
In this phase, you will be authenticating the credentials of the client. The
client will be asked to enter the username and password on the terminal. The
client will forward the request to the main server, and the main server will
encrypt this information and again forward this request to the credential
server. The credentials server would have all the encrypted credentials (both
username and password would be encrypted) of the registered users, but it
would not have any information about the encryption scheme. The information
about the encryption scheme would only be present at the main server. The
encryption scheme would be as follows:
- Offset each character and/or digit by 4.
- The scheme is case sensitive.
- Special characters (including spaces and/or the decimal point) will not be encrypted or changed.
Phase 1A
Client sends the authentication request to the main server over TCP
connection.
Constraints:
- The username will be of lower case characters (5~50 chars).
- The password will be case sensitive (5~50 chars).
Upon running the client using the following command, the user will be prompted
to enter the username and password:
./client
Please enter the username:
Please enter the password:
This unencrypted information will be sent to the main server over TCP, the
main server will encrypt this information and send it to the credential
server, which takes us to phase-1B.
Phase 1B
Main server forwards the authentication request to the credentials server over
UDP.
Phase 2
Phase 2A
serverC sends the result of the authentication request to serverM over a UDP
connection.
In this phase we check the result of the authentication request sent to the
serverC and communicate the result back to serverM. Once we receive the
authentication request at serverC,
The authentication request will contain the encrypted form of the username and
the password. At serverC, once the authentication request is received, the
serverC should first check if the username in the authentication request
matches with any of the usernames present in the cred.txt file. If the
username exists, it secondly checks if the password in the authentication
request is the same as the password corresponding to the same username in the
cred.txt file (It should be a case-sensitive match). If both the checks are
passed then serverC sends an authentication pass message to the serverM using
UDP. If either of the conditions fail then the serverC sends an authentication
fail message to the serverM (along with the reason for failure - username does
not exist or password does not match). You can use any type of encoding to
notify the main server that the authentication has passed or failed. For
example: Send 0 to serverM to indicate that the authentication request has
failed (no username), send 1 to serverM to indicate that the authentication
request has failed (password does not match) and 2 to serverM to indicate that
the authentication request has passed. Or PASS indicates that the
authentication request has passed, FAIL_NO_USER indicates that the
authentication request has failed (no username), and FAIL_PASS_NO_MATCH
indicates that the authentication request has failed (password does not
match).
Phase 2B
serverM sends the result of the authentication request to the client over a
TCP connection.
The result of the authentication request (Pass or Fail-with reason) is sent to
the client from the main server over TCP (any encoding can be used similar to
Phase 2A) and the result is displayed on the client screen. Please check the
on-screen messages section for further information. If the result of the
authentication request is a failure then the client will have two more
attempts to enter the correct username and password (a total of 3 attempts).
If the authentication request fails (in the first or second attempt), Phases
1A, 1B, 2A and 2B have to be repeated. If all of the attempts fail then the
client shuts down after indicating that all 3 attempts failed (Please check
the on-screen messages section for further information). If the result of the
authentication request is Pass then the client can move to Phase 3. The client
shuts down only if all the 3 authentication attempts have failed. If any of
the authentication attempts pass then the client stays on until it is manually
shut down.
Phase 3
In this phase, you are required to implement sending the request from client
to main server and then forwarding the request from the central registration
to the backend server.
Phase 3A
In this part, you will implement the client sending a query to the central
registration server. Your client should show a promote of
Please enter the course code to query:
Assuming the student entered:
EE450
And then the client program will promote:
Please enter the category (Credit / Professor / Days / CourseName):
The student will choose which category to search for, they may enter:
Professor
Your client should send this request to the main server via TCP connection.
You are allowed to use any type of encoding. For example, you can use integer
number 1 to represent EE and 0 to represent CS, or you can just use ascii EE
and CS to represent the two departments. Similarly, you can use integer
numbers to represent them. The main server will first extract the department
information from the query and decide which department server has the
corresponding information.
For the on-screen output, upon sending the request to the main server, your
client should output an on-screen message. When receiving the information from
the client, your main server should output an on-screen message. See the ON
SCREEN MESSAGES table for details.
Phase 3B
In this part, your main server will send the query information to the backend
department server via UDP connection. Your main server should output an on-
screen message upon sending the request to the backend server. After getting
the query information, the department server would look through its stored
local information to obtain the corresponding course information.
If the course was founded, print out:
The course information has been founded: The
If not, print out:
Didn’t find the course:
See the ON SCREEN MESSAGES table for details.
Phase 4
Phase 4B
At the end of Phase 3, the responsible Department server should have the query
information ready. The query information is first sent back to the Main server
using UDP and print out an on-screen message.
Phase 4B
When the Main server receives the result, it needs to print out an on-screen
message, forward the result to the Client using TCP and print out an on-screen
message.
When the client receives the result, it will print out the query information
and the prompt messages for a new request as follows:
The
—–Start a new request—-
Please enter the course code to query:
See the ON SCREEN MESSAGES table for details.
Extal Credits
If you want to earn 10 extra points, you can implement an extra functionality
where a user can query N courses (N [ 10) at once and receive the
corresponding information of all categories from different back-end servers
respectively. To be more specific, the input format on the client side is:
Note: the maximum number of CourseCode is less than 10 and there is a
whitespace between each CourseCode.
The request is sent to the main server using TCP. After receiving the packet,
the main server will parse it and send one or two request(s) to the backend
server(s). The one containing EE courses should be sent to the EE Department
server, and the other containing CS courses should be sent to the CS
Department server. The corresponding server will respond to the main server
with all information of all categories. The main server will combine two
responses from backend servers together and prepare one response message to
the client. The final results shown at the client side should maintain the
order of courses that the user input. For example, after the prompt shown on
the client’s terminal:
Please enter the course code to query:
The client inputs the following CouseCodes:
EE450 EE669 CS402
The following table will be shown on the client’s terminal:
CourseCode: Credits, Professor, Days, Course Name
EE450: 4, Ali Zahid, Tue;Thu, Introduction to Computer Networks
EE669: 4, Jay Kuo, Mon;Wed, Multimedia Data Compression
CS402: 4, William Cheng, Mon;Wed, Operating Systems (Note: there is no need to print those vertical and horizontal lines in the above table)
NOTE: The extra points will be added to the full 100 points. The maximum
possible points for this socket programming project is 110 points.
Process Flow/ Sequence of Operations:
- Your project grader will start the servers in this sequence: serverM, serverC, serverEE, serverCS, Client in five different terminals.
- Once all the ends are started, the servers and clients should be continuously running unless stopped manually by the grader or meet certain conditions as mentioned before.
Required Port Number Allocation
The ports to be used by the clients and the servers for the exercise are
specified in the following table:
Note: Major points will be lost if the port allocation is not as per the below
description.
Submission files and folder structure
Your submission should have the following folder structure and the files (the
examples are of .cpp, but it can be .c files as well):
- ee450_lastname_firstname_uscusername.tar.gz
- ee450_lastname_firstname_uscusername
- client.cpp
- serverM.cpp
- serverC.cpp
- serverCS.cpp
- serverEE.cpp
- Makefile
- readme.txt (or) readme.md
The grader will extract the tar.gz file, and will place all the input data
files in the same directory as your source files. The executable files should
also be generated in the same directory as your source files. So, after
testing your code, the folder structure should look something like this:
- ee450_lastname_firstname_uscusername
- ee450_lastname_firstname_uscusername
- client.cpp
- serverM.cpp
- serverC.cpp
- serverCS.cpp
- serverEE.cpp
- Makefile
- readme.txt (or) readme.md
- client
- serverM
- serverC
- serverCS
- serverEE
- ee.txt
- cs.txt
- cred.txt
Note that in the above example, the input data files (ee.txt, cs.txt and
cred.txt) will be manually placed by the grader, while the ‘make all’ command
should generate the executable files.