Developing a Simple Chat Program in C++
Introduction
In this article, we will write a simple chat program using C++. This program can establish a connection between the client and server, allowing users to send and receive messages. We will utilize the Sockets API to achieve this functionality. This project is a great exercise that helps improve your understanding of network programming.
Environment Requirements
To run the example code, you will need:
- A C++ compiler (such as g++, Visual Studio)
- An operating system that supports POSIX standards (like Linux) or WSA support on Windows
- Basic knowledge of C++
Project Structure
Our project consists of two main parts:
- Server: Listens for connections from clients, receives and forwards messages.
- Client: Establishes a connection with the server and allows the user to input messages to send.
Next, we will start with the server.
1. Server Code
Below is an example implementation of the server for the simple chat program:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <unistd.h> // for close()
#include <arpa/inet.h> // for sockaddr_in and inet_ntoa()
#include <sys/socket.h>
#define PORT 8080
#define BUFFER_SIZE 1024
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[BUFFER_SIZE] = {0};
// Create socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
std::cerr << "Socket creation failed" << std::endl;
return -1;
}
// Bind the socket to the specified address and port unless failed
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
std::cerr << "Set socket options failed" << std::endl;
return -1;
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
std::cerr << "Bind failed" << std::endl;
return -1;
}
// Start listening for connection requests
if (listen(server_fd, 3) < 0) {
std::cerr << "Listen failed" << std::endl;
return -1;
}
while (true) {
std::cout << "Waiting for connections..." << std::endl;
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,(socklen_t*)&addrlen))<0) {
std::cerr << "Accept failed" << std::endl;
exit(EXIT_FAILURE);
}
while(true) {
memset(buffer, '\0', BUFFER_SIZE);
ssize_t valread = read(new_socket , buffer , BUFFER_SIZE);
if(valread <= 0){
break;
}
buffer[valread] = '\0';
std::cout << "Client: " << buffer << std::endl;
send(new_socket , buffer , valread , MSG_CONFIRM);
std::cout << "Server: echoing " << buffer << std::endl;
}
}
return 0;
}
Code Explanation:
- First, we create a socket for TCP/IP communication.
- Using the
<span>bind</span>
function, we bind it to the specified IP address and port. <span>listen</span>
function puts the socket in a listening state, waiting for client connection requests.- Once a client requests a connection, we use
<span>accept</span>
to accept it and create a new socket for communication; - Then we loop to read the data sent by the client, print it out, and return the received data back to the client (echo functionality).
2. Client Code
Below is an example implementation of the corresponding client:
#include <bits/stdc++.h>
using namespace std;
#define PORT 8080
int main() {
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hello = "Hello from client";
char buffer[1024] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
std::cout << "Socket creation error" << std::endl;
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
std::cout << "Invalid address/ Address not supported" << std::endl;
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
std::cout << "Connection Failed" << std::endl;
return -1;
}
send(sock , hello , strlen(hello) , 0);
std::cout << "Hello message sent" << std::endl;
valread = read(sock , buffer, 1024);
std::cout << buffer << std::endl;
return 0;
}
Code Explanation:
- Similar to the server, we first create a socket and use the
<span>connect</span>
method to connect to the previously created server.
Overall, this simplified chat program demonstrates how to set up basic network communication using C++, helping beginners understand the workings of the Sockets API. If you want to expand further, consider adding multithreading, a graphical interface, and other features.
I hope this article helps you get started with C++ network programming!
Conclusion
This article introduced how to build a simple instant messaging application using C++, implementing basic information exchange between a server and client, deepening the understanding of network programming concepts, the Sockets API, and practical coding skills, laying a good foundation for future learning.