-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathServer5.c
More file actions
130 lines (105 loc) · 4.02 KB
/
Server5.c
File metadata and controls
130 lines (105 loc) · 4.02 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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "Ws2_32.lib")
#define close(fd) closesocket(fd)
// Automatic Winsock initialization and cleanup
static void init_winsock() __attribute__((constructor));
static void cleanup_winsock() __attribute__((destructor));
static void init_winsock() {
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
fprintf(stderr, "WSAStartup failed\n");
exit(EXIT_FAILURE);
}
}
static void cleanup_winsock() {
WSACleanup();
}
#define PORT 8080 // Port number for the server
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int addrlen = sizeof(address);
char buffer[1024] = {0};
// Initialize fd_set
fd_set readfds;
FD_ZERO(&readfds); // Initialize the set
int max_fd;
// 1. Create socket
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd == -1) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
// 2. Bind socket to an IP/Port
address.sin_family = AF_INET; // IPv4
address.sin_addr.s_addr = INADDR_ANY; // Any IP address
address.sin_port = htons(PORT); // Host to Network Short
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("Binding failed");
close(server_fd);
exit(EXIT_FAILURE);
}
// 3. Listen for incoming connections
if (listen(server_fd, 1) < 0) {
perror("Listening failed");
close(server_fd);
exit(EXIT_FAILURE);
}
printf("Server is listening on port %d...\n", PORT);
// Add server socket to readfds
FD_SET(server_fd, &readfds);
max_fd = server_fd; // Initialize max_fd with the server socket
while (1) {
// Create a copy of readfds to pass to select
fd_set temp_fds = readfds;
// Use select to wait for activity on any socket
int activity = select(max_fd + 1, &temp_fds, NULL, NULL, NULL);
if (activity < 0) {
perror("select error");
break;
}
// Check for new incoming connections
if (FD_ISSET(server_fd, &temp_fds)) {
new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen);
if (new_socket < 0) {
perror("Accepting connection failed");
continue;
}
FD_SET(new_socket, &readfds); // Add new client to the fd_set
if (new_socket > max_fd) max_fd = new_socket; // Update max_fd if necessary
printf("New client connected: %d\n", new_socket);
}
// Handle communication with existing clients
for (int i = 0; i <= max_fd; i++) {
if (i != server_fd && FD_ISSET(i, &temp_fds)) {
// Clear the buffer for the new message
memset(buffer, 0, sizeof(buffer));
// Receive data from the client
int bytes_read = recv(i, buffer, sizeof(buffer) - 1, 0);
if (bytes_read <= 0) {
// Client disconnected
printf("Client %d disconnected\n", i);
close(i);
FD_CLR(i, &readfds); // Remove from fd_set
} else {
// Forward data to other clients
buffer[bytes_read] = '\0';
printf("Received from client %d: %s\n", i, buffer);
for (int j = 0; j <= max_fd; j++) {
if (j != server_fd && j != i && FD_ISSET(j, &readfds)) {
send(j, buffer, bytes_read, 0); // Send message to all other clients
}
}
}
}
}
}
// Close the server socket after exiting the loop
close(server_fd);
return 0;
}