-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchat_server.c
More file actions
140 lines (117 loc) · 4.01 KB
/
Copy pathchat_server.c
File metadata and controls
140 lines (117 loc) · 4.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// chat_server.c
// Author: Harsh Kukutkar
// Description: Multi-Client Chat Server with Username Support using TCP sockets and pthreads
// Compilation: gcc chat_server.c -o server -lpthread
// Run Command: ./server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
#define MAX_USERS 10
#define MSG_LENGTH 1024
int connectedClients[MAX_USERS];
int totalClients = 0;
pthread_mutex_t clientLock = PTHREAD_MUTEX_INITIALIZER;
// Send a message to all connected clients except the sender
void sendToAll(char *message, int senderSocket) {
pthread_mutex_lock(&clientLock);
for (int i = 0; i < totalClients; i++) {
if (connectedClients[i] != senderSocket) {
send(connectedClients[i], message, strlen(message), 0);
}
}
pthread_mutex_unlock(&clientLock);
}
// Handle communication with a single client
void *handleClient(void *arg) {
int clientSocket = *(int *)arg;
free(arg);
char userName[50];
char messageBuffer[MSG_LENGTH];
int msgLength;
// Receive username from client
msgLength = recv(clientSocket, userName, sizeof(userName), 0);
if (msgLength <= 0) {
close(clientSocket);
return NULL;
}
userName[msgLength] = '\0';
printf("%s connected.\n", userName);
// Notify others that this user joined
char joinMsg[MSG_LENGTH];
snprintf(joinMsg, sizeof(joinMsg), "%s joined the chat.\n", userName);
sendToAll(joinMsg, clientSocket);
// Keep listening for messages from this client
while ((msgLength = recv(clientSocket, messageBuffer, MSG_LENGTH, 0)) > 0) {
messageBuffer[msgLength] = '\0';
printf("%s", messageBuffer);
sendToAll(messageBuffer, clientSocket);
}
// Handle disconnect
printf("%s disconnected.\n", userName);
close(clientSocket);
// Remove this client from list
pthread_mutex_lock(&clientLock);
for (int i = 0; i < totalClients; i++) {
if (connectedClients[i] == clientSocket) {
for (int j = i; j < totalClients - 1; j++) {
connectedClients[j] = connectedClients[j + 1];
}
totalClients--;
break;
}
}
pthread_mutex_unlock(&clientLock);
// Announce that the user left
snprintf(joinMsg, sizeof(joinMsg), "%s left the chat.\n", userName);
sendToAll(joinMsg, clientSocket);
return NULL;
}
int main() {
int serverSocket, newClientSocket;
struct sockaddr_in serverAddress, clientAddress;
socklen_t clientAddrLen = sizeof(clientAddress);
// Create TCP socket
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket < 0) {
perror("Socket creation failed");
exit(1);
}
// Set up server details
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(8080);
serverAddress.sin_addr.s_addr = INADDR_ANY;
// Bind socket to address
if (bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) < 0) {
perror("Bind failed");
exit(1);
}
// Start listening for clients
listen(serverSocket, 5);
printf("Chat Server started on port 8080...\n");
while (1) {
newClientSocket = accept(serverSocket, (struct sockaddr*)&clientAddress, &clientAddrLen);
if (newClientSocket < 0) {
perror("Accept failed");
continue;
}
pthread_mutex_lock(&clientLock);
if (totalClients >= MAX_USERS) {
printf("Maximum clients reached. Connection refused.\n");
close(newClientSocket);
pthread_mutex_unlock(&clientLock);
continue;
}
connectedClients[totalClients++] = newClientSocket;
pthread_mutex_unlock(&clientLock);
int *clientPtr = malloc(sizeof(int));
*clientPtr = newClientSocket;
pthread_t clientThread;
pthread_create(&clientThread, NULL, handleClient, (void*)clientPtr);
pthread_detach(clientThread);
}
close(serverSocket);
return 0;
}