| Network Topology |
|---|
![]() |
This is a C/C++ socket programming project that simulates a web registration system.
Concretely, client sets up TCP connection with serverM to get authorized or query information on a course.
serverM acts as a gateway, process the request from client, and forward a request via UDP to corresponding backend servers if needed.
serverC is a credential server that verified whether a given username-password pair is valid.
serverEE and serverCS store the information of courses offered
by EE / CS department, respectively.
In this project, I implement Phase 0-4 according to the project specification (exclude the extra part).
What's more, almost all messages exchanged between two ends follows a header-payload format (see Format of Exchanged Message part) to distinguish different stages.
Specifically, the serverM will generate and store a random token in its memory when a user got authorized, and then send to the client.
When client is in the stage of query course information, it should contain such a token to prove it is authorized.
Such a design fits the scenario that client will new a TCP connection per request and follows the industry paradigm.
.
├── Makefile // Makefile of this project
├── client.cpp // source code of client, prompts user to login, and query course information
├── convention.cpp // source code of agreements or utilities shared by communication entities
├── convention.hpp // header of agreements, e.g., status code, request/response header
├── cred.txt // mocked database file, containing encrypted usernames and passwords, only be accessible by the serverC
├── cred_unencrypted.txt // unencrypted version of `cred.txt`, only for testing
├── cs.txt // mocked database file, containing CS course information, only be accessible by the serverCS
├── ee.txt // mocked database file, containing EE course information, only be accessible by the serverEE
├── readme.md // README of this project
├── serverC.cpp // source code of serverC, parses `cred.txt` and stores username-password pairs in a hashmap
├── serverCS.cpp // source code of serverCS, parses `cs.txt` and stores coursecode-info pairs in a hashmap
├── serverEE.cpp // source code of serverEE, parses `ee.txt` and stores coursecode-info pairs in a hashmap
└── serverM.cpp // source code of serverM, processes request from `client` and makes reponses after contacting other backend servers
-
Set up input files
serverC,serverCS, andserverEErequire to read files to function properly. By default, these files are hardcoded in their source code in the format likeconst string COURSE_FILE = "cs.txt";. You can change if needed. -
Compile
In Ubuntu, compile with
make all. -
Start
Run in the following sequence (but in 5 different terminals):
./serverM ./ServerC ./serverEE ./serverCS ./client
Basically, each exchanged message will contain a header and a payload, separated by a single space.
Since all the headers are added and parsed by the programs, the payload, which may come from user input, will not be broken.
-
Authentication request (from
clienttoserverM/ fromserverMtoserverC)["ARQ" "<number_of_username_chars>" ""]
"ARQ" is a prefix served as a header for
serverMorserverCto recognize the message type. "<number_of_username_chars>" is the number of chars of the username typed by the user, this design is to fit the scenario whenusernamecontains a possible delimiter used by the server. "" and "" are what user typed, with\r\nremoved. -
Authentication result
2.1 From
serverCtoserverM:["ARS" "<result_code>" "<dummy_info>"]
"ARS" is a prefix served as a header for
serverMto recognize the message type. "<result_code>" is one ofPASS,FAIL_NO_USER, andFAIL_PASS_NO_MATCHas defined inconvention.hpp. "<dummy_info>" is just appended for format consistency, and will be omitted byserverM.2.2 From
serverMtoclient:["ARS" "<result_code>" "<token_or_dummy_info>"]
"ARS" is a prefix served as a header for
clientto recognize the message type. "<result_code>" is one ofPASS,FAIL_NO_USER, andFAIL_PASS_NO_MATCHas defined inconvention.hpp. "<token_or_dummy_info>" will be theserverMgenerated token if user got authorized, otherwise, it will be dummy info. -
Query request
3.1 From
clienttoserverM:["QRQ" "" "<course_code>" ""] "QRQ" is a prefix served as a header for
serverMto recognize the message type. "" is whatserverMhas sent toclientwhen authorized, it served as an identifier. "<course_code>" and "" are what user typed.3.2 From
serverMtoserverCSorserverEE:["QRQ" "<course_code>" ""] "ARQ" is a prefix served as a header for
serverCSorserverEEto recognize the message type. "<course_code>" and "" are what user typed. -
Query result (from
serverCSorserverEEtoserverM/ fromserverMtoclient)["QRS" "<result_code>" ""] "QRS" is a prefix served as a header for
serverMorclientto recognize the message type. "<result_code>" is one ofFOUND_COURSE_INFOorNO_COURSE_CODEas defined inconvention.hpp. "" is the info theclientis looking for if the request is valid, otherwise, it will be dummy info.
Beej's Guide to Network Programming
Remove tailing \r and \n from string
