Introduction – Real Time Chat Application
A Real-Time Chat Application allow users to send and receive messages instantly over a network. Implementing such an application in C++ involves utilizing socket programming for network communication and managing message exchange between clients and a central server.
Key Concepts of Project
- Server
- Client
- Networking
Algorithm Approach
- Server Side
- Initialize a server socket and bind it to a specific port.
- Listen for incoming connections from clients.
- Accept client connections and manage them in separate threads or asynchronously.
- Receive messages from clients and broadcast them to all connected clients.
- Maintain a list of connected clients and handle disconnections gracefully.
- Client Side
- Initialize a client socket and connect to the server.
- Send messages to the server.
- Receive messages from the server and display them to the user.
- Handle user input for sending messages.
- Message Exchange
- Define a protocol for message exchange (e.g., message format, command structure).
- Serialize and deserialize messages to/from byte streams for network transmission.
- Implement mechanisms for error handling, connection timeouts, and reconnections.
C++ Project Codes
Here’s a simplified outline of a real-time chat application using sockets in C++:
Server Implementation
// Server.cpp #include <iostream> #include <thread> #include <vector> #include <cstring> #include <arpa/inet.h> #include <unistd.h> constexpr int PORT = 8080; constexpr int MAX_CLIENTS = 10; std::vector<int> clients; void handleClient(int clientSocket) { char buffer[1024] = {0}; while (true) { int valread = read(clientSocket, buffer, 1024); if (valread == 0) { std::cout << "Client disconnected\n"; break; } std::cout << "Client message: " << buffer << std::endl; // Broadcast message to all clients (excluding sender) for (int client : clients) { if (client != clientSocket) { send(client, buffer, strlen(buffer), 0); } } memset(buffer, 0, sizeof(buffer)); } close(clientSocket); } int main() { int serverSocket, clientSocket; struct sockaddr_in address; int addrlen = sizeof(address); // Creating socket file descriptor if ((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) == 0) { std::cerr << "Socket creation failed\n"; return -1; } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); // Binding socket to port if (bind(serverSocket, (struct sockaddr *)&address, sizeof(address)) < 0) { std::cerr << "Bind failed\n"; return -1; } // Listening for incoming connections if (listen(serverSocket, MAX_CLIENTS) < 0) { std::cerr << "Listen failed\n"; return -1; } std::cout << "Server listening on port " << PORT << std::endl; while (true) { if ((clientSocket = accept(serverSocket, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) { std::cerr << "Accept failed\n"; return -1; } std::cout << "New client connected\n"; clients.push_back(clientSocket); std::thread clientThread(handleClient, clientSocket); clientThread.detach(); // Detach the thread to run independently } return 0; }
Client Implementation
// Client.cpp #include <iostream> #include <cstring> #include <arpa/inet.h> #include <unistd.h> constexpr int PORT = 8080; constexpr char SERVER_IP[] = "127.0.0.1"; int main() { int clientSocket; struct sockaddr_in serverAddress; char message[1024] = {0}; if ((clientSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) { std::cerr << "Socket creation failed\n"; return -1; } serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(PORT); if (inet_pton(AF_INET, SERVER_IP, &serverAddress.sin_addr) <= 0) { std::cerr << "Invalid address/ Address not supported\n"; return -1; } if (connect(clientSocket, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) < 0) { std::cerr << "Connection failed\n"; return -1; } std::cout << "Connected to server\n"; while (true) { std::cout << "Enter message: "; std::cin.getline(message, 1024); send(clientSocket, message, strlen(message), 0); std::cout << "Message sent\n"; } return 0; }