0% found this document useful (0 votes)
21 views22 pages

Real-Time Chat System with IPC

The project implements a multi-user real-time chat application using Inter-Process Communication (IPC) with System V message queues, allowing concurrent communication among clients managed by a central server. It features secure user authentication through file-based storage, ensuring reliable message delivery and process synchronization. The system demonstrates foundational operating system concepts and provides insights into concurrent programming and secure applications.

Uploaded by

Ot Bodam
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views22 pages

Real-Time Chat System with IPC

The project implements a multi-user real-time chat application using Inter-Process Communication (IPC) with System V message queues, allowing concurrent communication among clients managed by a central server. It features secure user authentication through file-based storage, ensuring reliable message delivery and process synchronization. The system demonstrates foundational operating system concepts and provides insights into concurrent programming and secure applications.

Uploaded by

Ot Bodam
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Project Title: Real Time Chat System using Interprocess

communication

Student Name: Tejas Shailendra Kadam

Roll Number: 24BBS0210

Faculty Guide: Dr. Priyadharsini M

Department & Institution Name: SCOPE, VIT Vellore

Date of Submission: October 27, 2025


Abstract

This project implements a multi-user real-time chat application leveraging core


Operating System concepts, especially Inter-Process Communication (IPC)
through System V message queues. It enables concurrent communication among
multiple clients managed by a central server.
User authentication is handled using file-based credential storage, ensuring secure
registration and login. The server controls user sessions, routes messages, and
manages active clients efficiently.
The system showcases essential OS concepts such as process synchronization,
mutual exclusion, and secure concurrent communication, preventing data conflicts
and maintaining message integrity.
Overall, the project demonstrates practical use of IPC mechanisms,
synchronization techniques, and file operations, combining theory with a
functional real-world chat system.
Table of Contents

Abstract

Table of Contents

1. 1. Introduction

1.1 Background & Motivation

1.2 Objectives of the Project

1.3 Problem Statement

2. 2. System Design & Methodology

2.1 Algorithms & Pseudocode

2.2 System Architecture

2.3 Flowcharts

2.4 Tools and OS Concepts Used

3. 3. Implementation

3.1 Coding Details

3.2 Data Structures

3.3 Critical Functions


Introduction

Background and Motivation

Real-time communication platforms are now integral for social and enterprise interactions. Building
such systems requires careful orchestration of concurrent processes, secure user management, and
low-latency data transfer—relying fundamentally on operating system primitives. Traditional chat
systems use modern tools like WebSockets and message brokers, but implementing these concepts
at the OS level using IPC sheds light on foundational computing concepts.

Objectives

 Develop a real-time, multi-client chat server using IPC message queues.

 Incorporate file-backed user authentication for registration and login.

 Showcase process synchronization in message handling and user management.

 Explore challenges and solutions in concurrent, secure multi-user communication.

Problem Statement

Traditional chat systems rely on high-level frameworks or external databases, whereas this project
aims to achieve the same functionality at the operating system level, demonstrating how core OS
principles such as process synchronization, message passing, and concurrent access management can
be utilized to build a functional multi-user communication system.
The system should ensure that:

 Multiple clients can register and log in simultaneously.

 Messages are delivered reliably using System V message queues.

 User credentials are stored securely using file-based storage.

 The server efficiently manages active sessions and message routing without data loss or race
conditions.
System Design Methodology

Algorithm

Server Logic

 Receive login or message requests from clients via message queue.

 On login, validate credentials, assign unique client type, notify all users.

 On message, redirect the data to the intended recipient’s message queue type.

 On termination, gracefully clean up message queue resources.

Client Logic

 Register/login via file operations.

 Send messages using message queue.

 Fork child process to receive real-time incoming messages.

Authentication Module

 On registration, append username & password to file if the username is unique.

 On login, check input credentials against file entries for a match.

System Architecture

 Central server process: Interacts with multiple client processes over System V message queues.

 Clients: Interactive console applications, send/receive messages, maintain separate processes


for input and output.

 User database: Simple flat file with ID, username, and hashed password (for demonstration,
plain text is used).

 See the diagram below.


Flowchart
Tools and OS Concepts Used

 Language: C with standard POSIX environment.

 IPC: System V message queues for asynchronous inter-process (client-server) communication.

 File Handling: Storage of user credentials and authentication data. [4]

 Process Model: Multi-processing via fork in client for simultaneous input/output.

 Signals: For server termination and resource cleanup.

 Synchronization: Achieved through message queue primitives, atomicity of message delivery.

Implementation

Coding Details

1. Server Program

• Header Files Used:


#include <sys/ipc.h>, #include <sys/msg.h>, #include <stdio.h>, #include
<stdlib.h>, #include <string.h>, #include <unistd.h>

• Major Functions:
• Message Queue Creation:
The server uses msgget() with a unique key generated by ftok() to create or
connect to the message queue.
• User Authentication:
User credentials are stored in a local file ([Link]).
On login or registration, the server performs file I/O using fopen(), fprintf(), and
fscanf() for reading and writing user data.
• Message Handling:
The server continuously receives messages using msgrcv().
Depending on message type:
• REGISTER: Adds new user credentials to the file.
• LOGIN: Validates username and password.
• MSG: Routes chat messages to the appropriate recipient.
• Synchronization:
The server uses a single message queue to handle multiple clients concurrently and
assigns unique message types for targeted delivery.
• Graceful Shutdown:
On termination, the message queue is deleted using msgctl(msqid, IPC_RMID,
NULL).

2. Client Program

• Header Files Used:


#include <sys/ipc.h>, #include <sys/msg.h>, #include <stdio.h>, #include
<stdlib.h>, #include <string.h>, #include <unistd.h>

• Major Functions:
• Connection to Server:
Each client connects to the server via the same message queue key generated using
ftok().

• User Login & Registration:


The client sends formatted messages like "LOGIN username password" or
"REGISTER username password" to the server.

• Message Sending:
After login, clients can send messages using msgsnd() with a message type equal to
the receiver’s unique ID or name hash.
• Concurrent Message Reception:
The client forks a child process to continuously listen for incoming messages using
msgrcv(), enabling real-time chat behavior.

• User Interface:
The terminal-based UI shows online users and message exchanges.
Server and Messaging Logic

Manages client registration, assigns each client a unique message type, routes messages between
clients, and maintains a list of active users.

Authentication System

Handles registration and login via file operations, checking for duplicate usernames and validating
credentials.

Main Data Structures

struct message {
long type; // For identifying the receiver/client in the queue
char sender[^50];
char receiver[^50];
char text[MAX_TEXT];
};

struct client_info {
char username[^50];
char password[^50];
int msg_type; // Each client's unique queue type
};

User Registration & Login Overview

struct User {
int id;
char username[MAX_USERNAME];
char password[MAX_PASSWORD];
};

Representative Code Excerpt: Authentication

void create_user() {
// Opens file, checks existing usernames, assigns unique ID, writes new record.
}

int login_user(char *username_out) {


// Opens file, validates credentials, returns user ID or error.
}
Process Management

 Server: Persistent process, handles all incoming requests in a loop, updates clients on user
status changes.

 Client: Forks a receiver child process for real-time updates, parent handles user input.

 Authentication: Performed by separate CRUD module (CrudUser.c) prior to starting chat


session.

Compilation and Execution

 Compile client, server, and registration modules:

gcc server.c -o server


gcc client.c -o client
gcc CrudUser.c -o CrudUser

 Start server, register/login users, then run clients.

Screenshots/Outputs

server.c
client.c

Termial 1 / Client 1

Terminal 2 / Client 2
Terminal 3/ Client 3

Analysis of Results

 Registration/Login: New users register successfully; duplicate usernames prevented.

 Real-Time Chat: Simultaneous messaging works; clients receive and display real-time updates.

 Concurrency: Facilitated via message queues, no message loss or race conditions observed.

 Resource Management: Server handles interrupts for clean queue deletion.[2][1]

Performance Metrics

 Concurrent Users: System tested with up to 10 concurrent clients.

 Message Latency: Instantaneous local delivery (on campus network/localhost).

 Resource Use: Minimal CPU due to blocking message receive logic; footprint scales with active
clients.
Mapping with OS Concepts

 IPC: System V message queues abstract away complexities of manual buffer management.

 Atomic Operations: Each send/receive operation is atomic, reducing need for locks.

 Signals: Used for prompt and safe cleanup upon exit.

 File Operations: Persistent storage of authentication data, a demonstration of OS file


management primitives.

Challenges and Solutions

 Client Management: Assigning unique types for each client using sequential logic.

 Duplicate Usernames: Prevented by checking file end-to-end before registration. [5]

 Safe Termination: SIGINT handler deletes IPC queue to avoid resource leaks.

 Offline Messaging: Not in this implementation; queues clear on client termination (for simplicity).

Conclusion

This project delivers a functional real-time chat system built on foundational operating system
principles. By utilizing System V message queues and file handling, the implementation provides a
deep insight into concurrent programming, process communication, and secure stateful applications.
The approach can be extended to support advanced features such as offline messaging, encrypted
communication, and persistence through integration with databases. The hands-on experience gained
illustrates the link between academic theory and practical systems programming.
References

1. Silberschatz, Galvin, Gagne. Operating System Concepts, 10th Edition.

2. System V IPC - Linux man pages, [Link]

3. GeeksforGeeks: "File Handling in C" , "User Authentication in C" [4][5]

4. Algocademy: "How to Design a Real-Time Chat Application"[1]

5. Redis Pub/Sub for chat systems[2]

6. CrazyEngineers. "User Login and Registration using Files in C"[6]

7. StackOverflow, System Design Interview Posts[7][1

8. [Link]

9. [Link]

10. [Link]

11. [Link]

12. [Link]

13. [Link]

14. [Link]

15. [Link]

16. [Link]

17. [Link]
Appendix

Server Code (server.c)

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include <unistd.h>

#include <signal.h>

#define MAX_CLIENTS 10

#define MAX_TEXT 256

struct message {x

long type; // used for receiver

char sender[50];

char receiver[50];

char text[MAX_TEXT];

};

struct client_info {

char username[50];

char password[50];

int msg_type; // each client’s type

};

int msgid;

struct client_info clients[MAX_CLIENTS];

int client_count = 0;

void cleanup(int sig) {

msgctl(msgid, IPC_RMID, NULL);

printf("\nServer shutting down. Queue removed.\n");

exit(0);

}
void register_client(const char *username, const char *password, int msg_type) {

strcpy(clients[client_count].username, username);

strcpy(clients[client_count].password, password);

clients[client_count].msg_type = msg_type;

client_count++;

int find_client_type(const char *username) {

for (int i = 0; i < client_count; i++)

if (strcmp(clients[i].username, username) == 0)

return clients[i].msg_type;
return -1;

void send_online_users() {

char list[MAX_TEXT] = "";

strcat(list, "Online: ");

for (int i = 0; i < client_count; i++) {

strcat(list, clients[i].username);

if (i < client_count - 1) strcat(list, ", ");

for (int i = 0; i < client_count; i++) {

struct message msg;


[Link] = clients[i].msg_type;

strcpy([Link], list);

msgsnd(msgid, &msg, sizeof(msg) - sizeof(long), 0);

int main() {

signal(SIGINT, cleanup);

key_t key = ftok("server", 65);

msgid = msgget(key, 0666 | IPC_CREAT);

if (msgid == -1) {
perror("msgget");

exit(1);

printf("Server started...\n");

struct message msg;

while (1) {

if (msgrcv(msgid, &msg, sizeof(msg) - sizeof(long), 1, 0) == -1)

continue;

if (strncmp([Link], "LOGIN", 5) == 0) {

char username[50], password[50];


sscanf([Link], "LOGIN %s %s", username, password);

int client_type = 10 + client_count; // assign unique type

register_client(username, password, client_type);

struct message response;

[Link] = client_type;

snprintf([Link], sizeof([Link]), "Login successful!");

msgsnd(msgid, &response, sizeof(response) - sizeof(long), 0);

send_online_users();

else if (strncmp([Link], "MSG", 3) == 0) {


char receiver[50], content[MAX_TEXT];

sscanf([Link], "MSG %s %[^\n]", receiver, content);

int recv_type = find_client_type(receiver);

if (recv_type == -1) continue;

struct message send_msg;

💬
send_msg.type = recv_type;

snprintf(send_msg.text, sizeof(send_msg.text), " %s: %s", [Link], content);

msgsnd(msgid, &send_msg, sizeof(send_msg) - sizeof(long), 0);

}
}

return 0;

Client Code (client.c)

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include <unistd.h>

#define MAX_TEXT 256

struct message {

long type;

char sender[50];

char receiver[50];

char text[MAX_TEXT];

};

int main() {

key_t key = ftok("server", 65);

int msgid = msgget(key, 0666 | IPC_CREAT);


if (msgid == -1) {

perror("msgget");

exit(1);

struct message msg;

char username[50], password[50];

printf("Username: ");

scanf("%s", username);

printf("Password: ");

scanf("%s", password);
[Link] = 1; // send to server

strcpy([Link], username);

snprintf([Link], sizeof([Link]), "LOGIN %s %s", username, password);

msgsnd(msgid, &msg, sizeof(msg) - sizeof(long), 0);

printf(" ⏳ Waiting for login response...\n");

// wait for login success to get client type

struct message login_msg;

int my_type = -1;

while (1) {

if (msgrcv(msgid, &login_msg, sizeof(login_msg) - sizeof(long), 0, 0) != -1) {

if (strstr(login_msg.text, "Login successful!")) {

printf("%s TYPE=%ld\n", login_msg.text, login_msg.type);

my_type = login_msg.type;

break;

if (fork() == 0) {

struct message recv_msg;

while (1) {

📩
if (msgrcv(msgid, &recv_msg, sizeof(recv_msg) - sizeof(long), my_type, 0) != -1) {

printf("\n %s\n", recv_msg.text);

fflush(stdout);

exit(0);

while (1) {

char receiver[50], text[MAX_TEXT];

printf("To (username): ");


scanf("%s", receiver);

printf("Message: ");

getchar();

fgets(text, sizeof(text), stdin);

text[strcspn(text, "\n")] = 0;

struct message send_msg;

send_msg.type = 1; // send to server

strcpy(send_msg.sender, username);

snprintf(send_msg.text, sizeof(send_msg.text), "MSG %s %s", receiver, text);

msgsnd(msgid, &send_msg, sizeof(send_msg) - sizeof(long), 0);

return 0;

User Management Code (CrudUser.c)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FILE_NAME "[Link]"
#define MAX_USERNAME 50
#define MAX_PASSWORD 50
struct User {
int id;
char username[MAX_USERNAME];
char password[MAX_PASSWORD];
};
void create_user() {
struct User user, temp;
FILE *fp = fopen(FILE_NAME, "a+");
if (!fp) {
perror("Error opening file");
return;
}
int last_id = 0;
while (fscanf(fp, "%d %s %s", &[Link], [Link], [Link]) != EOF) {
if ([Link] > last_id)
last_id = [Link];
}
rewind(fp);
char new_username[MAX_USERNAME];
printf("Enter username: ");
scanf("%s", new_username);
while (fscanf(fp, "%d %s %s", &[Link], [Link], [Link]) != EOF) {
if (strcmp([Link], new_username) == 0) {
printf("Username already exists!\n");
fclose(fp);
return;
}
}
[Link] = last_id + 1;
strcpy([Link], new_username);
printf("Enter password: ");
scanf("%s", [Link]);
fprintf(fp, "%d %s %s\n", [Link], [Link], [Link]);
fclose(fp);
printf(" User created successfully! Your ID: %d\n", [Link]);
}
int login_user(char *username_out) {
struct User user;
char uname[MAX_USERNAME], pass[MAX_PASSWORD];
FILE *fp = fopen(FILE_NAME, "r");
if (!fp) {
printf(" No user database found! Please register first.\n");
return -1;
}
printf("Username: ");
scanf("%s", uname);
printf("Password: ");
scanf("%s", pass);
while (fscanf(fp, "%d %s %s", &[Link], [Link], [Link]) != EOF) {
if (strcmp(uname, [Link]) == 0 && strcmp(pass, [Link]) == 0) {
fclose(fp);
strcpy(username_out, [Link]);
return [Link];
}
}
fclose(fp);
return -1;
}
int main() {
int choice;
char username[MAX_USERNAME];
while (1) {
printf("\n========== CHAT SYSTEM ==========\n");
printf("1. Register New User\n");
printf("2. Login\n");
printf("3. Exit\n");
printf("=================================\n");
printf("Enter choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
create_user();
break;
case 2: {
int client_id = login_user(username);
if (client_id != -1) {
printf("Login successful!\n");
printf("Your ID: %d, Username: %s\n", client_id, username);
printf("\nNow run: ./client %d %s\n", client_id, username);
} else {
printf(" Invalid credentials!\n");
}
break;
}
case 3:
printf("Goodbye!\n");
exit(0);
default:
printf("Invalid choice!\n");
}
}
return 0;
}

Common questions

Powered by AI

The client architecture involves interactive console applications, where each client registers or logs in via file operations. After authentication, a child process is forked to handle real-time message reception using msgrcv(), enabling the main process to handle user inputs concurrently. This architecture separates input/output operations, ensuring real-time communication while maintaining a terminal-based user interface for displaying online users and messages .

System V message queues facilitate asynchronous inter-process communication in the chat system by handling message passing between the server and clients. Each client is assigned a unique message type, which allows the server to route messages specifically to intended recipients. This approach removes complexities associated with manual buffer management and supports atomic operations for concurrent message handling, contributing to secure and efficient message delivery without data loss or race conditions .

The chat system illustrates core OS concepts such as interprocess communication (IPC) using System V message queues for managing asynchronous message exchange. Synchronization is achieved through atomic message operations, while file handling demonstrates persistence in user authentication. Signal handling for server termination shows resource management. These concepts deep dive into how processes coordinate, interact, and securely manage shared data in a real-world system, thereby enhancing understanding of operating system fundamentals .

The server manages multiple client sessions by using a single message queue to handle all clients concurrently. It assigns a unique message type for each client on successful login, facilitating targeted message delivery. The server maintains a list of active clients and updates them on user status changes, ensuring efficient session management without race conditions. Resource cleanup is ensured by handling signals like SIGINT for queue deletion on server shutdown .

The chat system separates user input and output processes by forking a child process for message reception during client operation. The parent process captures user input while the child continuously listens for incoming messages using msgrcv(). This concurrent handling of input and output ensures that messages are sent and received in real-time, providing seamless communication without blocking either process .

The chat system employs process synchronization through the use of System V message queue primitives. This includes utilizing atomicity of message send/receive operations to prevent data conflicts and ensure message integrity. By assigning unique message types and using these for targeted message delivery, the system avoids simultaneous access issues, maintaining a clean and orderly message queue .

Challenges in the chat system include client management for unique message type assignments and handling connections without duplicate usernames. These were addressed by using sequential logic for type assignments and end-to-end file checks before user registration. Additionally, safe termination was ensured by using SIGINT signals for resource cleanup, though offline messaging was not implemented, simplifying queue management for active sessions only .

Signals play a crucial role in the server's resource management by ensuring prompt and safe cleanup upon exit. Utilizing SIGINT signals, the system safely deletes IPC queues during server shutdown, preventing resource leaks and ensuring the integrity of operating system resources. This mechanism exemplifies robust OS-level handling of process termination and resource deallocation .

User authentication in the chat system is implemented through file-based credential storage, where user details such as username and password are stored in a local file (users.txt). The registration process checks for unique usernames, and during login, credentials are validated against existing records using file I/O operations with fopen(), fprintf(), and fscanf().

Implementing a chat system at the OS level using IPC provides direct interaction with operating system primitives like process synchronization and message queues, which high-level frameworks abstract away. This approach focuses on foundational computing concepts and offers hands-on experience with low-level concurrency management, unlike high-level frameworks that often use WebSockets and external databases for simplicity and ease of scalability .

You might also like