https://github.com/rajnandinithopte/socket-programming--computer-networks
A UNIX socket programming project that implements a meeting scheduler using TCP and UDP communication. The system includes a client, main server, and two backend servers to process meeting requests and determine common available time slots efficiently. Built using C/C++ on Ubuntu, following POSIX socket programming principles.
https://github.com/rajnandinithopte/socket-programming--computer-networks
computernetworks cpp posix socket-programming tcp ubuntu unix
Last synced: 12 months ago
JSON representation
A UNIX socket programming project that implements a meeting scheduler using TCP and UDP communication. The system includes a client, main server, and two backend servers to process meeting requests and determine common available time slots efficiently. Built using C/C++ on Ubuntu, following POSIX socket programming principles.
- Host: GitHub
- URL: https://github.com/rajnandinithopte/socket-programming--computer-networks
- Owner: rajnandinithopte
- Created: 2025-02-02T07:29:56.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-02-03T05:19:42.000Z (over 1 year ago)
- Last Synced: 2025-05-16T09:08:53.640Z (about 1 year ago)
- Topics: computernetworks, cpp, posix, socket-programming, tcp, ubuntu, unix
- Language: C++
- Homepage:
- Size: 198 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Socket-Programming-Computer-Networks
## Developed a **meeting scheduling system** using **UNIX socket programming** with TCP and UDP communication.
---
## 🔹 Tech Stack
**Programming Language:** C++
**Networking:** UNIX Sockets, TCP, UDP
**Development Environment:** Ubuntu 22.04
**Libraries & Tools:**
- **Beej’s Guide to Network Programming** - Socket programming reference
- **POSIX Sockets** - Implementing client-server communication
- **Makefile** - For compiling and running executables
---
## 🔹 System Overview

This project implements a **meeting scheduler** that:
- Enables users to **schedule a meeting with a group of people**.
- Uses **a client, main server, and two backend servers**.
- Communicates between **client & main server using TCP** and **main server & backend servers using UDP**.
- Finds **common available meeting slots** for multiple users.
The system consists of **four main components**:
1. **Client (client.cpp)** - Takes user input (names) and requests available time slots.
2. **Main Server (serverM.cpp)** - Manages user requests and forwards them to backend servers.
3. **Backend Server A (serverA.cpp)** - Stores availability data for a subset of users.
4. **Backend Server B (serverB.cpp)** - Stores availability data for another subset of users.
---
## 🔹 Workflow & Communication
1. **Boot-up Phase**
- The **Main Server (ServerM)** starts and listens for incoming connections.
- **Backend Servers (ServerA & ServerB)** load user availability data from input files (`a.txt`, `b.txt`).
- **Backend Servers** send the list of stored users to **Main Server** via **UDP**.
2. **Request & Forwarding Phase**
- The **Client** sends a list of participants to the **Main Server** via **TCP**.
- The **Main Server** determines which **Backend Server** stores the required users' availability.
- The **Main Server** forwards the request to the correct **Backend Server** via **UDP**.
3. **Scheduling Phase**
- Each **Backend Server** finds the common available time slots for the requested users.
- The **Backend Server** returns the result to the **Main Server**.
4. **Reply & Final Intersection Phase**
- The **Main Server** aggregates availability from both **Backend Servers**.
- The final list of available meeting times is sent back to the **Client** via **TCP**.
---
## 🔹 Code Files & Their Purpose
### 1. **serverM.cpp** (Main Server)
- Handles **client requests** and forwards them to the correct backend servers.
- Creates a **TCP socket** to communicate with the **Client**.
- Creates a **UDP socket** to communicate with **Backend Servers**.
- Determines if the user belongs to `serverA` or `serverB` based on input files.
- **Aggregates** the final meeting time slots from both backend servers.
### 2. **serverA.cpp** (Backend Server A)
- Creates a **UDP socket** to communicate with the **Main Server**.
- Reads **user availability data** from `a.txt` and stores it in a **map data structure**.
- Finds **common available time slots** for requested users.
- Sends the result back to **Main Server**.
### 3. **serverB.cpp** (Backend Server B)
- Creates a **UDP socket** to communicate with the **Main Server**.
- Reads **user availability data** from `b.txt` and stores it in a **map data structure**.
- Finds **common available time slots** for requested users.
- Sends the result back to **Main Server**.
### 4. **client.cpp** (Client Program)
- Creates a **TCP socket** to communicate with **Main Server**.
- Accepts **usernames as input** (max 10 usernames, max 20 characters each).
- Sends **user requests** to the **Main Server**.
- Receives and **displays the available meeting slots**.
---
## 🔹 Constraints Considered While Developing the Algorithm
### **🔸 Efficiency**
- **User list processing (hashmap lookup):** `O(U)`
- **Sorting user intervals before merging:** `O(N log N)`
- **Merging time slots for intersection:** `O(N)`
- **Sending & receiving data from backend servers:** `O(K)`
- **Overall Time Complexity:** `O(U log U + N log N)`
**Final Complexity:**
`O(U log U + N log N)`,
where **U = number of users in request** and **N = number of time intervals processed**.
- **Pairwise intersection checking** ensures that only **valid overlapping intervals** are considered.
- **Memory Efficiency:**
- Uses **maps or hash tables** to store and retrieve user availability efficiently.
- Can handle **large input sizes (up to 200 lines per file) without excessive memory consumption**.
---
### **🔸 Input Validation & Formatting**
- **Ensures Correct Time Intervals:**
- **Start time < End time** for every time slot.
- Each interval must be **strictly increasing** (i.e., `t[i]_end < t[i+1]_start`).
- **Handles Formatting Issues:**
- **Removes unwanted spaces** before processing.
- Ensures that **usernames contain only lowercase letters** (as required).
- **Rejects invalid or malformed time intervals** (e.g., `[[1,1]]` or `[[10,5]]` are invalid).
- **Handles Cases Where No Intersection Exists:**
- If **no overlapping time slots** exist, the algorithm correctly returns **an empty list (`[]`)**.
---
### **🔸 Scalability & Performance**
- **Handles Large Datasets Efficiently:**
- The algorithm is optimized for processing **large input files (up to 200 lines each)**.
- Efficient use of **sorting and merging** prevents excessive computation time.
- **Designed to Process Multiple Users in One Query:**
- Supports up to **10 usernames per request**.
- Uses **iterative intersection** to process multiple users efficiently.
---
### **🔸 Robust Handling of Edge Cases**
- **Handles Single User Queries Efficiently:**
- If a **single user** is requested, the backend directly **returns their full availability** without unnecessary computations.
- **Handles Very Short and Very Long Time Slots:**
- Works with **small intervals** like `[[1,2]]` and **large intervals** like `[[0,100]]`.
- **Correctly Processes Scenarios Where Users Exist on Different Backend Servers:**
- Ensures that the **Main Server** correctly assigns **each user to the correct backend server**.
- Aggregates results from multiple backend servers correctly.
---
### **🔸 Consistency & Accuracy**
- **Results Are Always Sorted and Maintain Valid Overlaps:**
- Ensures **final intersection lists remain sorted**.
- Guarantees that **all overlapping intervals are preserved**.
- **Ensures All Time Slots Are Fully Processed:**
- Even if a user has **multiple separate availability slots**, the algorithm **correctly computes intersections across all of them**.
- **Adheres to On-Screen Message Requirements:**
- **Backend servers print** results after computing intersections.
- **Main Server correctly forwards** results and prints appropriate messages.
---
# 🔹 Algorithm for Finding Common Meeting Slots
The **meeting scheduler algorithm** ensures that a meeting can be scheduled by finding **common available time slots** among multiple users stored across two backend servers.
---
## **🔸Step 1: Backend Servers Read and Store Data**
- **Backend Server A (ServerA)** reads `a.txt` and stores availability data for **a subset of users**.
- **Backend Server B (ServerB)** reads `b.txt` and stores availability data for **another subset of users**.
- Each **backend server** sends a list of usernames it manages to the **Main Server** via **UDP**.
### **Example Data in `a.txt` and `b.txt`**
```
a.txt:
alice;[[1,10],[11,12]]
bob;[[5,9],[11,15]]
b.txt:
amy;[[4,12]]
charlie;[[3,8],[9,15]]
```
At this stage, **ServerA manages Alice and Bob**, while **ServerB manages Amy and Charlie**.
---
## **🔸 Step 2: Client Sends a Meeting Request**
1. The **client** enters names of participants.
2. The **client program** sends the list to the **Main Server** via **TCP**.
3. The **Main Server** checks which **backend server** stores each user’s data.
4. It **splits the list** and **forwards requests via UDP** to the respective backend servers.
### **Example Client Request**
```
User Input: alice bob amy
```
The **Main Server** identifies:
- `alice` and `bob` → Stored in **ServerA**
- `amy` → Stored in **ServerB**
Thus, the **Main Server** sends:
- **To ServerA**: Request for **alice, bob** availability.
- **To ServerB**: Request for **amy** availability.
---
## **🔸 Step 3: Backend Servers Compute Individual Intersections**
Each backend server:
1. **Finds the time availability** for requested users.
2. **Computes the pairwise intersection** of time slots.
3. **Sends the result back to the Main Server**.
### **Case 1: One User**
- If only **one user** is in the request, the backend server directly sends **their availability**.
#### **Example**
```
User Input: amy
```
Amy’s availability from `b.txt`: `[[4,12]]`
Backend Server B returns:
```
[[4,12]]
```
---
### **Case 2: Two Users**
If two users exist, the backend server:
- **Fetches both users’ time slots**.
- **Finds overlapping intervals**.
#### **Example (Alice & Bob)**
```
Alice: [[1,10],[11,12]]
Bob: [[5,9],[11,15]]
```
**Algorithm computes intersections**:
- `[1,10]` and `[5,9]` → Intersection: **`[5,9]`**
- `[11,12]` and `[11,15]` → Intersection: **`[11,12]`**
#### **Backend Server A returns result**
```
[[5,9],[11,12]]
```
---
### **Case 3: More than Two Users**
If there are **three or more** users, the algorithm:
1. **Finds the intersection between the first two users**.
2. **Uses the result to find an intersection with the next user**.
3. **Repeats this process until all users' availability is considered**.
#### **Example (Alice, Bob, and Amy)**
```
Alice: [[1,10],[11,12]]
Bob: [[5,9],[11,15]]
Amy: [[4,12]]
```
**Step 1: Find Alice & Bob’s intersection**
```
[[5,9],[11,12]]
```
**Step 2: Find intersection of result with Amy**
```
[[5,9],[11,12]] ∩ [[4,12]]
```
**Final Intersection Result**:
```
[[5,9],[11,12]]
```
Backend Servers send results to the **Main Server**.
---
## **🔸 Step 4: Main Server Computes Final Intersection**
1. **Main Server receives results** from **ServerA and ServerB**.
2. **It runs another intersection algorithm** between the two sets.
#### **Example**
```
Server A result: [[6,7],[10,12],[14,15]]
Server B result: [[3,8],[9,15]]
```
**Final Intersection Computed by Main Server**
```
[[6,7],[10,12],[14,15]]
```
**Main Server sends this to the client.**
---
## **🔸 Step 5: Client Receives and Displays Final Meeting Slots**
Once the **client receives the final result**, it **displays the available meeting times**:
#### **Example Client Output**
```
Time intervals [[6,7],[10,12],[14,15]] work for alice, bob, amy.
```
**If no common slots exist, it returns** `[]`.
---
# 🔹Port Assignments
| Process | Protocol | Port Number|
|----------|----------|------------|
| Server A | UDP | **21+XXX** |
| Server B | UDP | **22+XXX** |
| Server M | UDP | **24+XXX** |
| Server M | UDP | **23+XXX** |
| Client | TCP | **Dynamic**|
Each process communicates using the specified **ports** to ensure correct message routing.
# 🔹How to Run the Meeting Scheduling System
## 1. Compile the Code
Use the `Makefile` to compile all server and client programs:
```sh
make all
```
This will generate the following executable files:
- **serverM** (Main Server)
- **serverA** (Backend Server A)
- **serverB** (Backend Server B)
- **client** (Client Program)
---
## 2. Start the Servers and Client
### Step 1: Start the Main Server
Open a new terminal window and run:
```sh
./serverM
```
**Expected Output:**
```
Main Server is up and running.
```
### Step 2: Start Backend Server A
In another terminal window, run:
```sh
./serverA
```
**Expected Output:**
```
Server A is up and running using UDP on port .
Server A finished sending a list of usernames to Main Server.
```
### Step 3: Start Backend Server B
In a third terminal window, run:
```sh
./serverB
```
**Expected Output:**
```
Server B is up and running using UDP on port .
Server B finished sending a list of usernames to Main Server.
```
### Step 4: Start the Client
In a fourth terminal window, run:
```sh
./client
```
**Expected Output:**
```
Client is up and running.
Please enter the usernames to check schedule availability:
```
---
## 3. Enter User Input in the Client
Once the client is running, enter a list of usernames:
```
Please enter the usernames to check schedule availability:
alice bob charlie
```
The client will process the request and return available time slots.
---
## 4. Communication Flow & Expected Messages
### 1. Client to Main Server
After sending the request:
```
Client finished sending the usernames to Main Server.
```
If some usernames do not exist:
```
Client received the reply from Main Server using TCP over port :
do not exist.
```
If usernames exist:
```
Main Server received the request from client using TCP over port .
Found located at Server . Send to Server .
```
### 2. Main Server to Backend Servers
```
Main Server received the username list from server A using UDP over port .
Main Server received the username list from server B using UDP over port .
```
Each backend server will process its data and return the intersection:
```
Server received the usernames from Main Server using UDP over port .
Found the intersection result: <[[t1_start, t1_end], [t2_start, t2_end], … ]> for .
Server finished sending the response to Main Server.
```
### 3. Main Server Processing the Final Result
```
Main Server received from server A the intersection result using UDP over port :
<[[t1_start, t1_end], [t2_start, t2_end], … ]>.
Main Server received from server B the intersection result using UDP over port :
<[[t1_start, t1_end], [t2_start, t2_end], … ]>.
Found the intersection between the results from server A and B:
<[[t1_start, t1_end], [t2_start, t2_end], … ]>.
Main Server sent the result to the client.
```
### 4. Client Receives the Final Meeting Time
```
Client received the reply from Main Server using TCP over port :
Time intervals <[[t1_start, t1_end], [t2_start, t2_end], … ]> works for .
```
---
## 5. Stop the Servers
Once you're done testing, stop all servers and the client by pressing:
```sh
CTRL + C
```
This will terminate the processes.
## 🔹 References
This project references concepts from:
1. **Beej's Guide to Network Programming**: [Beej's Guide](http://www.beej.us/guide/bgnet/)
- Chapter 3: `structs`
- Chapter 4: `socket(), bind(), connect(), listen(), accept(), send()/recv(), sendto()/recvfrom()`
- Chapter 9.12: `htons()`
- Chapter 9.24: `struct sockaddr_in`