Socket Programming in C for Beginners | Group Chat Application | Multi Threaded + Multiple Users|E4|
Table of Contents
Introduction
In this tutorial, we'll learn how to create a group chat application using socket programming in C. This application will allow multiple clients to connect to a server and communicate with each other in real time. By the end of this tutorial, you'll have a solid understanding of socket programming concepts, threading, and how to implement a simple chat server.
Step 1: Setting Up the Environment
- Choose an IDE: You can use any IDE of your choice, such as CLion or Code::Blocks.
- Create a new project: Name it “socket_server” for the server-side application and “socket_client” for the client-side application.
- Include necessary headers: Make sure to include the following headers in your C files:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <pthread.h>
Step 2: Creating the Server
-
Create the socket:
- Use the
socket()function to create a server socket. - Specify the address family (IPv4), socket type (TCP), and protocol (0).
int server_socket = socket(AF_INET, SOCK_STREAM, 0); - Use the
-
Bind the socket:
- Define the server address structure and bind the socket to an IP and port.
struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; // Listen on all interfaces server_addr.sin_port = htons(2000); // Port number bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)); -
Listen for incoming connections:
- Use the
listen()function to allow the server to accept incoming connections.
listen(server_socket, 10); // 10 is the backlog for incoming connections - Use the
-
Accept clients:
- Use a loop to accept multiple clients. Create a new thread for each accepted client.
while (1) { int client_socket = accept(server_socket, (struct sockaddr*)&client_addr, &addr_size); pthread_t tid; pthread_create(&tid, NULL, handle_client, (void*)&client_socket); }
Step 3: Handling Client Connections
-
Create a function to handle client communication:
- This function will receive messages from the client and broadcast them to other connected clients.
void* handle_client(void* arg) { int client_socket = *(int*)arg; char buffer[1024]; while (1) { int bytes_received = recv(client_socket, buffer, sizeof(buffer), 0); if (bytes_received <= 0) { break; // Connection closed } // Broadcast the message to other clients broadcast_message(buffer, client_socket); } close(client_socket); return NULL; } -
Broadcast messages:
- Implement a function that sends messages to all connected clients except the sender.
void broadcast_message(char* message, int sender_socket) { for (int i = 0; i < accepted_clients_count; i++) { if (accepted_clients[i] != sender_socket) { send(accepted_clients[i], message, strlen(message), 0); } } }
Step 4: Creating the Client
-
Create the client socket:
- Similar to the server, use the
socket()function.
int client_socket = socket(AF_INET, SOCK_STREAM, 0); - Similar to the server, use the
-
Connect to the server:
- Define the server address and connect using the
connect()function.
struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(2000); // Port number inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr); // Server IP connect(client_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)); - Define the server address and connect using the
-
Send and receive messages:
- Use a loop to send messages from the client and listen for incoming messages from the server.
while (1) { char message[1024]; fgets(message, sizeof(message), stdin); send(client_socket, message, strlen(message), 0); // Listen for incoming messages in a separate thread }
Step 5: Implementing Multi-threaded Client Listening
-
Create a separate thread for receiving messages:
- This thread will continuously listen for incoming messages from the server.
void* listen_for_messages(void* arg) { int client_socket = *(int*)arg; char buffer[1024]; while (1) { int bytes_received = recv(client_socket, buffer, sizeof(buffer), 0); if (bytes_received <= 0) { break; // Connection closed } printf("Received: %s\n", buffer); } return NULL; } -
Start the thread:
- Call this thread when the client connects to the server.
pthread_t tid; pthread_create(&tid, NULL, listen_for_messages, (void*)&client_socket);
Conclusion
You have successfully created a multi-threaded group chat application using socket programming in C. This application allows multiple clients to connect to a server and communicate with each other in real time. As next steps, consider adding features like user authentication, chat history, or deploying the application to a server for broader access. Experiment with error checking and memory management to enhance the robustness of your application.