Implementing a Simple Network Chat Room in C
In this tutorial, we will create a simple network chat room using the C programming language. This project will demonstrate how to implement communication between a client and a server using socket programming.
1. Development Environment Setup
Before we begin, please ensure you have the following development tools installed:
- GCC Compiler
- A text editor (such as vim, nano, or any IDE)
2. Basics of Network Programming
Before diving into actual coding, let’s understand some basic concepts:
- Socket: An endpoint for inter-process communication.
- Server Socket: Used to listen for client requests and accept connections.
- Client Socket: Used to initiate a connection to the server.
2.1 TCP/IP Protocol
Our chat room will operate based on the TCP protocol, as it provides reliable data transmission. In this example, the server will run continuously and wait for multiple client connections.
3. Structure of the Network Chat Room
We need two components:
- Server Side – Receives messages from clients and forwards them to all connected users.
- Client Side – Used to send and receive messages.
Below are the steps to implement the code for these two components.
4. Writing the Server-Side Code
First, let’s write the chat server-side code. This code is responsible for handling multiple client requests and can broadcast messages to all connected users.
4.1 server.c Source Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // For close()
#include <arpa/inet.h> // For sockaddr_in
#include <pthread.h>
#define PORT 8888
#define MAX_CLIENTS 10
#define BUFFER_SIZE 1024
int clients[MAX_CLIENTS];
int client_count = 0;
void* handle_client(void* arg) {
int sock = *(int*)arg;
char buffer[BUFFER_SIZE];
int n;
while ((n = recv(sock, buffer, sizeof(buffer) - 1, 0)) > 0) {
buffer[n] = '\0';
for (int i = 0; i < client_count; i++) {
if (clients[i] != sock) {
send(clients[i], buffer, n + 1, 0);
}
}
}
close(sock); // Remove this client from the list of clients.
for (int i = 0; i < client_count; i++) {
if (clients[i] == sock) {
clients[i] = clients[--client_count];
break;
}
}
return NULL;
}
int main() {
int server_sock, new_sock;
struct sockaddr_in server_addr, client_addr;
// Create socket
server_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// Configure server_addr structure
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr= INADDR_ANY;
server_addr.sin_port= htons(PORT);
// Bind socket to specified address and port
bind(server_sock,(struct sockaddr *)&server_addr,sizeof(server_addr));
listen(server_sock, MAX_CLIENTS);
printf("Chat Server started on port %d\n", PORT);
while (client_count < MAX_CLIENTS) {
socklen_t addr_len = sizeof(client_addr);
new_sock = accept(server_sock,(struct sockaddr*)&client_addr,&addr_len);
if(client_count < MAX_CLIENTS) {
clients[client_count++] = new_sock;
pthread_t tid;
pthread_create(&tid,NULL,&handle_client,&new_sock);
printf("New connection accepted.\n");
}
}
close(server_sock);
return EXIT_SUCCESS;
}
Summary:
Run <span>gcc server.c -o server -lpthread</span>
to compile your chat server code.
This code mainly serves to:
- Create and bind a TCP socket.
- Listen for incoming connections and allocate a new thread for each valid connection to handle incoming message broadcasting to other clients (excluding the current sender).
Explanation of Different Parts:
<span>handle_client()</span>
function is responsible for reading information from each user and sending the data to other users.
Starting the Server
To start your chat service, execute the following command:
./server
Your server will now be listening on port 8888, waiting for clients to connect.
Writing the Client-Side Code
Below is the client-side code for the chat program, which implements a platform for quickly sending and receiving messages.
Client Source Code
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"
#include "arpa/inet.h"
#define PORT 8888
#define BUFFER_SIZE 1024
int main() {
char message[BUFFER_SIZE];
int sock;
struct sockaddr_in server_address;
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == -1) {
perror("Could not create socket");
return EXIT_FAILURE;
}
server_address.sin_family = AF_INET;
server_address.sin_port = htons(PORT);
server_address.sin_addr.s_addr = INADDR_ANY;
if (connect(sock, (struct sockaddr *)&server_address, sizeof(server_address)) < 0) {
perror("Connection failed");
return EXIT_FAILURE;
}
while (1) {
printf("Enter a message: ");
fgets(message, BUFFER_SIZE, stdin);
send(sock, message, strlen(message), 0);
if (strcmp(message, "exit\n") == 0) break;
}
close(sock);
return EXIT_SUCCESS;
}
Summary:
Compile using the command <span>gcc client.c -o client</span>
.
This code mainly serves to:
- Establish a connection to the chat service’s corresponding address and port;
- Continuously input character streams until a termination signal is received and properly close the access permissions.
Starting the Client
Please execute the following command to start multiple client windows to simulate different clients responding to activity:
./client
Open several windows and start them to create an initial dialogue environment for testing functionality!
Output the message you want to express, and by pressing enter, you will see that message displayed in all running chat interfaces. You can open multiple terminal modes for testing functionality actively!
Further Considerations
You may want to further expand this chat room system, such as adding a graphical user interface (GUI), encrypted transmission, saving chat history, etc. These can be great directions for you to explore and learn!
Happy coding!