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?
-
Compile with MinGW:
gcc chat.c -o chat.exe -lws2_32 -
Run as Server → choose
1 -
Run as Client → choose
2→ enter IP (127.0.0.1for 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