Implementing a Network Chat Room in C: Communication and Interface Design
In this article, we will learn how to implement a simple network chat room using the C programming language. We will divide it into two parts: the server side and the client side. Through these two parts, users can chat in real-time within the same local area network.
1. Environment Setup
Ensure that the following tools are installed in your development environment:
- GCC Compiler
- A text editor (such as VSCode, Sublime Text, etc.)
2. Basics of Network Programming
Before we start, we need to understand some basic concepts of network programming:
- Socket: An endpoint for inter-process communication.
- IP Address: A unique address that identifies a device.
- Port Number: A number that identifies a specific service or application.
3. Server-Side Code
First, let’s implement the server-side code. The server is responsible for listening to client requests and handling message forwarding.
3.1 Creating the Server Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080
#define MAX_CLIENTS 10
#define BUFFER_SIZE 1024
int clients[MAX_CLIENTS];
void broadcast_message(const char *message, int sender) {
for (int i = 0; i < MAX_CLIENTS; i++) {
if (clients[i] != -1 && clients[i] != sender) {
send(clients[i], message, strlen(message), 0);
}
}
}
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
// Initialize client array
memset(clients, -1, sizeof(clients));
// Create socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("Socket failed");
exit(EXIT_FAILURE);
}
// Set socket options
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt));
// Set socket address structure
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
// Bind socket to the specified IP and PORT
bind(server_fd, (struct sockaddr *)&address, sizeof(address));
// Start listening for connection requests, max connections = 3
listen(server_fd, MAX_CLIENTS);
printf("Server is listening on port %d\n", PORT);
while (1) {
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) >= 0) {
printf("New client connected: %d\n", new_socket);
for(int i=0; i<MAX_CLIENTS; i++) {
if(clients[i] == -1) {
clients[i] = new_socket;
break;
}
}
char buffer[BUFFER_SIZE];
while(1) {
memset(buffer, '\0', BUFFER_SIZE);
int bytes_read = read(new_socket , buffer , BUFFER_SIZE);
if(bytes_read <= 0){
printf("Client disconnected: %d\n", new_socket);
close(new_socket);
break;
}
printf("Message from client %d: %s\n", new_socket , buffer);
broadcast_message(buffer,new_socket);
}
}
}
return EXIT_SUCCESS;
}
3.2 Compiling and Running the Server
Use the following command to compile and run the server:
gcc server.c -o server
./server
4. Client-Side Code
Next, let’s implement the client-side code. The client is responsible for sending messages to the server and receiving information from other users.
4.1 Creating the Client Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080
#define BUFFER_SIZE 1024
int main() {
int sockfd;
struct sockaddr_in servaddr;
char buffer[BUFFER_SIZE];
// Create socket file descriptor
if ((sockfd = socket(AF_INET, SOCK_STREAM , IPPROTO_TCP)) == -1 ) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr,'\0',sizeof(servaddr));
// Fill service information structure
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
if(inet_pton(AF_INET,"127.0.0.1",&servaddr.sin_addr)<=0) {
perror("Invalid address or Address not supported");
exit(EXIT_FAILURE);
}
if(connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr))<0) {
perror("Connection Failed");
exit(EXIT_FAILURE);
}
while(1) {
printf("Enter message: ");
fgets(buffer , BUFFER_SIZE , stdin);
send(sockfd , buffer , strlen(buffer), MSG_NOSIGNAL );
memset(buffer,'\0',BUFFER_SIZE);
recv(sockfd , buffer , BUFFER_SIZE , MSG_WAITALL );
printf("%s\n" , buffer );
}
close(sockfd);
return EXIT_SUCCESS;
}
4.2 Compiling and Running the Client
Use the following command to compile and run multiple client instances:
gcc client.c -o client
./client # Execute this command multiple times in different terminals to start multiple client instances.
Conclusion
By following the above steps, you have successfully created a simple network chat room based on the C language. In this chat room, users can send messages to each other without the need for any additional software support. This is a great exercise to help you understand the basic concepts of network programming and how to utilize C for practical application development.
We hope you continue to explore more complex features, such as adding usernames, private messaging, etc.