29.9.25

Chat Application in C



Hey, everyone so I learned how to built a simple chat app in C. It’s nothing fancy like WhatsApp, but it works!

How It Works

  • Server: Listens on port 8080 and shares any client’s message with all others.

  • Client: Connects to the server, lets you type, and shows messages from others.

  • Threads & Locks: Each client runs on its own thread. Locks make sure data doesn’t crash.

Program:


#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <windows.h>

#pragma comment(lib, "ws2_32.lib")

#define PORT 8080
#define MAX_CLIENTS 10
#define BUFFER_SIZE 1024

SOCKET clients[MAX_CLIENTS];
int client_count = 0;
CRITICAL_SECTION cs;

void broadcast_message(char* msg, SOCKET sender) {
    EnterCriticalSection(&cs);
    for (int i = 0; i < client_count; i++) {
        if (clients[i] != sender) {
            send(clients[i], msg, (int)strlen(msg), 0);
        }
    }
    LeaveCriticalSection(&cs);
}

DWORD WINAPI handle_client(LPVOID arg) {
    SOCKET client_sock = *(SOCKET*)arg;
    free(arg);
    char buffer[BUFFER_SIZE];
    int read_size;

    while ((read_size = recv(client_sock, buffer, BUFFER_SIZE - 1, 0)) > 0) {
        buffer[read_size] = '\0';
        printf("Client: %s", buffer);
        broadcast_message(buffer, client_sock);
    }

    EnterCriticalSection(&cs);
    for (int i = 0; i < client_count; i++) {
        if (clients[i] == client_sock) {
            clients[i] = clients[client_count - 1];
            client_count--;
            break;
        }
    }
    LeaveCriticalSection(&cs);

    closesocket(client_sock);
    printf("Client disconnected.\\n");
    return 0;
}

DWORD WINAPI receive_messages(LPVOID arg) {
    SOCKET sock = *(SOCKET*)arg;
    char buffer[BUFFER_SIZE];
    int read_size;

    while ((read_size = recv(sock, buffer, BUFFER_SIZE - 1, 0)) > 0) {
        buffer[read_size] = '\\0';
        printf("%s", buffer);
    }

    printf("Disconnected from server.\\n");
    exit(0);
}

void start_server() {
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    InitializeCriticalSection(&cs);

    SOCKET server_sock = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    server_addr.sin_addr.s_addr = INADDR_ANY;

    bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr));
    listen(server_sock, 5);

    printf("Server running on port %d\\n", PORT);

    while (1) {
        SOCKET client_sock = accept(server_sock, NULL, NULL);
        if (client_sock == INVALID_SOCKET) continue;

        EnterCriticalSection(&cs);
        if (client_count < MAX_CLIENTS) {
            clients[client_count++] = client_sock;
        }
        LeaveCriticalSection(&cs);

        SOCKET* pclient = (SOCKET*)malloc(sizeof(SOCKET));
        *pclient = client_sock;
        CreateThread(NULL, 0, handle_client, pclient, 0, NULL);
    }

    closesocket(server_sock);
    DeleteCriticalSection(&cs);
    WSACleanup();
}

void start_client() {
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);

    char ip[50];
    printf("Enter server IP (localhost=127.0.0.1): ");
    scanf("%s", ip); 
    server_addr.sin_addr.s_addr = inet_addr(ip);

    if (connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) {
        printf("Connection Failed\\n");
        closesocket(sock);
        WSACleanup();
        exit(1);
    }

    printf("Connected! Type messages:\\n");
    CreateThread(NULL, 0, receive_messages, &sock, 0, NULL);

    char buffer[BUFFER_SIZE];
    while (1) {
        fgets(buffer, BUFFER_SIZE, stdin);
        send(sock, buffer, (int)strlen(buffer), 0);
    }

    closesocket(sock);
    WSACleanup();
}

int main() {
    int choice;
    printf("Choose mode: 1=Server, 2=Client: ");
    scanf("%d", &choice);

    if (choice == 1) start_server();
    else if (choice == 2) start_client();
    else printf("Invalid choice.\\n");

    return 0;
}

How to make it work?

  1. Compile with MinGW:

    gcc chat.c -o chat.exe -lws2_32
    
  2. Run as Server → choose 1

  3. Run as Client → choose 2 → enter IP (127.0.0.1 for local)

What I Learned

  • Sockets = computers sending/receiving data.

  • Threads = handle many people at once.

  • Locks = prevent memory conflicts.

I

No comments:

Post a Comment

rating System

Loading...

A Friendship Story of Learning Data Structures with C

Sr. No. DSU BLOGS CHAPTERS 1 Array Operations in C, The Group of Friendship (Create, Insert, Delete ...