Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit

EE450 Socket Programming Project

Part1

Fall 2023

Due Date:

Wednesday, October 18, 2023 11:59PM

(Hard Deadline, Strictly Enforced)

OBJECTIVE

The objective of project 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 email the TA your questions, come by TA’s office hours, or ask during the weekly discussion session. You can ask TAs any question about the content of the project, but TAs have the right to reject your request for debugging.

PROBLEM STATEMENT

In this part of the project, you will implement client-server socket programming using TCP. In a Student Performance Analysis system of a university,a client (student) would like to ask the Main server which Backend server that a department is associated with. A client sends a department name to the Main server and the Main server will search in its database and reply to the client with a Backend server ID.

Figure 1

The detailed operations to be performed by all the parties are described with the help of Figure 1. There are in total 3 communication endpoints, which are run in 3 individual terminal windows:

●   Client 1, Client 2, Client 3: represent three different users, send queries to main server.

●   Main server: store information, search, send responses to clients.

You  are highly  encouraged to use Beej’s  Guide  to  Network Programming to  complete this assignment. You can use code from Beej’s Guide as a starting point (remember to mention any code you take directly from other sources like Beej’s Guide in the README and your comments).

The  full  process  can  be  roughly  divided  into  three  phases,  and  their  communication  and computation steps are as follows:

Bootup

1.  [Computation]: Main server read the file list.txt and store the information.  2. [Communication]: Main server process wait for client processes to connect. 3. [Computation]: Clients run and ask the user to input a department name.

Query

1. [Communication]: Each client then establishes a TCP connection to the Main server and sends their queries (the department name) to the Main server.

A client can terminate itself only after it receives a reply from the server (in the Reply phase).

Main server maybe connected to the three clients at the sametime.

2. [Computation]: Once the Main server receives the queries, it decodes the queries and searches in the list with the received department name, obtaining the corresponding Backend server ID.

Reply

1. [Communication]: Main server prepares a reply message and sends the result to the appropriate client.

2. [Communication]: Clients receive the reply message from Main server and display it. Clients should keep active for further inputted queries, until the program is manually killed (Ctrl-C).

The format of list.txt is as follows.

;; 

;

Example list.txt:

1

ECE;CS;Physics

2

Art;Cinema

3

Accounting;Business

Assumptions on the list.txt file:

1.   Department names are letters. The length of a department name can vary from 1 letter to at most 20 letters. It may contain both capital and lowercase letters but does not contain any white spaces.

2.   Backend server IDs are non-negative integer numbers.

3.   There are at most 10 Backend server IDs in total.

4.   There is no additional empty line(s) at the beginning or the end of the file. That is, the whole list.txt do not contain any empty lines.

5.   For simplicity, there is no overlap of department names among different Backend servers. 6.   For a given Backend server, there maybe repeated department names.

7.   list.txt will not be empty.

8.   A Backend server will store at least one department names, and at most 100 department names.

An example list.txt is provided for you as a reference. Other list.txt will be used for grading, so you are advised to prepare your own files for testing purposes.

Source Code Files

Your implementation should include the source code files described below:

1. servermain:   You  must  name  your   code   file: servermain.c or servermain.cc or servermain.cpp (all small letters). Also, you must name the corresponding header file (if you have one; it is not mandatory) servermain.h (all small letters).

2. client: The name for this piece of code must be client.cor 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). There should be only one client file!!!

Note: Your compilation should generate separate executable files for each of the components listed above.

DETAILED EXPLANATION

Phase 1 -- Bootup

Main server program first boots up in this phase.

./servermain

While booting up, the servers must display a bootup message on the terminal. The format of the bootup message for Main server is given in the on-screen message table at the end of the document. As the boot up message indicates, Main server must listen on the appropriate port for incoming packets/connections.

As described in the previous section, the main server needs to read the text file and store the information. There are many ways to store the information, such as dictionary, array, vector, etc. You need to decide which format to use based on the requirement of the problem. You can use any format if it can give you correct results.

Once the main server programs have booted up, three client programs run. Each client displays a boot up message as indicated in the onscreen messages table. Note that the client code takes no input argument from the command line. The format for running the client code is:

./client

After running it, it should display messages to ask the user to enter a query department name (e.g., implement using std::cin):

./client

Client is up and running.

Enter Department Name:

For example, if the client 1 is booted up and asks for Backend server ID for department ECE, then the terminal displays like this:

./client

Client is up and running.

Enter Department Name: ECE

Main server has its unique port number specified in “PORT NUMBER ALLOCATION” section with the source and destination IP address as localhost/ 127.0.0.1. Clients use dynamic ports.

Clients and Main server are required to print out on-screen messages after executing each action as described in the “ON SCREEN MESSAGES” section. These messages will help with grading if the process did not execute successfully. Missing some of the on-screen messages might result in misinterpretation that your process failed to complete. Please follow the exact format when printing the on-screen messages.

Phase 2 -- Query

After  booting  up,  Clients  establish  TCP  connections  with  Main  server.  After  successfully establishing the connection, Clients send the input department name to Main server. Once this is sent, Clients should print a message in a specific format. Repeat the same steps for Client 2 and Client 3.

Main server then receives requests from three Clients. If the department name is not found, the Main server will printout a message (see the “On Screen Messages” section) and return to standby.

For a server to receive requests from several clients at the same time, the function fork() should be used for the creation of a new process.fork() function is used for creating a new process, which is called child process, which runs concurrently with the process that makes the fork() call (parent process).

For a TCP server, when an application is listening for stream-oriented connections from other hosts, it is notified of such events and must initialize the connection using accept(). After the connection  with the client is successfully established, the accept() function returns anon-zero descriptor for a  socket called the child socket. The server can then fork off a process using fork() function to  handle connection on the new socket and go back to wait on the original socket. Note that the  socket that was originally created, that is the parent socket, is going to be used only to listen to the  client requests, and it is not going to be used for computation or communication between client  and Main server. Child sockets that are created for a parent socket have the identical well-known  port number and IP address at the server side, but each child socket is created for a specific client.  Through using the child socket with the help of fork(), the server can handle the three clients  without closing any one of the connections.

Once the Main server receives the queries, it decodes the queries and searches in the list with the received department name, finding the corresponding backend server ID.

Phase 3 -- Reply

At the end of Phase 2, the Main server should have the result ready. The result is the Backend server  ID  that  the  department  is  associated  with.  The  result   should  be   sent  back  to  the corresponding client using TCP. The client will print out the backend server ID and then print out the messages for a new request as follows:

...

Department ECE is associated

-----Start a new query----- Enter Department Name:

with

backend

server

1.

See the ON SCREEN MESSAGES table for an example output table.

PORT NUMBER ALLOCATION

The ports to be used by the client and the servers are specified in the following table:

Table 1. Static and Dynamic assignments for TCP ports

Process

Dynamic Ports

Static Ports

Main Server

TCP(with client): 23xxx

Client 1

TCP

Client 2

TCP

Client 3

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: 23319 for the Main Server, etc. Port number of all processes print port number of their own.

Table 2. Main Server on-screen messages

Event

On-screen Messages

Booting up (only while starting):

Main server is up and running.

Upon reading the department lists:

Main server has read the department list from list.txt.

Print the counting results of which department a backend server is responsible for:

(Repeated departments should be counted only once!)

Total number of Backend Servers: <num>

Backend Servers contains distinct departments

Backend Servers contains distinct departments

For example:

Total num of Backend Servers: 3

Backend Servers 1 contains 3 distinct departments Backend Servers 2 contains 5 distinct departments Backend Servers 3 contains 8 distinct departments

Upon receiving the input from the client:

Main server has received the request on Department

from client using TCP over port

number>


If the input department name

could not be found, send the error message to the client:

does not show up in backend server < Backend Server ID 1, Backend Server ID 2, …>

(Print all backend server IDs!)

The Main Server has sent Department Name: Not found to client  using TCP over port server

TCP port number>

If the input department name

could be found, decide which backend server contains related information about the input

department name:

shows up in backend server < Backend Server ID>