123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <sys/select.h>
- #define PORT 5000
- #define MAX_CLIENTS 10
- #define BUFFER_SIZE 256
- void error(const char *msg) {
- perror(msg);
- exit(1);
- }
- void main()
- {
- int server_fd;
- int client_fd[MAX_CLIENTS] = {0}; // Array to store client socket descriptors
- struct sockaddr_in server, client;
- fd_set readfds, copyfds;
- int max_fd, new_socket, activity, i, valread, sd;
- socklen_t addr_len = sizeof(client);
- char buffer[BUFFER_SIZE];
- // Create a TCP socket
- server_fd = socket(AF_INET, SOCK_STREAM, 0);
- if (server_fd < 0)
- {
- error("Error opening socket.");
- }
- // Prepare the sockaddr_in structure
- server.sin_family = AF_INET;
- server.sin_addr.s_addr = INADDR_ANY;
- server.sin_port = htons(PORT);
- // Allow reuse of addresses
- int opt = 1;
- setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
- // Bind the socket to the port
- if (bind(server_fd, (struct sockaddr *)&server, sizeof(server)) < 0)
- {
- error("Binding failed");
- }
- // Listen for incoming connections
- if (listen(server_fd, 5) < 0)
- {
- error("Listening failed");
- }
- printf("Listening on port %d...\n", PORT);
- while(1)
- {
- FD_ZERO(&readfds);
- FD_SET(server_fd, &readfds);
- max_fd = server_fd;
- // Add child sockets to the set
- for (i = 0; i < MAX_CLIENTS; i++)
- {
- sd = client_fd[i];
- if (sd > 0)
- {
- FD_SET(sd, &readfds);
- }
- if (sd > max_fd)
- {
- max_fd = sd;
- }
- }
- // Wait for an activity on one of the sockets
- activity = select(max_fd + 1, &readfds, NULL, NULL, NULL);
- if (activity < 0)
- {
- error("Select error");
- }
- // If something happened on the server socket, then it's an incoming connection
- if (FD_ISSET(server_fd, &readfds))
- {
- new_socket = accept(server_fd, (struct sockaddr *)&client, &addr_len);
- if (new_socket < 0)
- {
- error("Accept error");
- }
- printf("New connection from %s on socket %d\n", inet_ntoa(client.sin_addr), new_socket);
- // Add new socket to array of sockets
- for (i = 0; i < MAX_CLIENTS; i++)
- {
- if (client_fd[i] == 0)
- {
- client_fd[i] = new_socket;
- break;
- }
- }
- }
- // Check all clients for incoming messages
- for (i = 0; i < MAX_CLIENTS; i++)
- {
- sd = client_fd[i];
- if (FD_ISSET(sd, &readfds))
- {
- // Check if it was for closing, and also read the incoming message
- valread = read(sd, buffer, sizeof(buffer));
- if (valread > 0)
- {
- buffer[valread] = '\0'; // Null-terminate the received string
- printf("Message from client: %s\n", buffer);
- // Broadcast the message to all other clients
- for (int j = 0; j < MAX_CLIENTS; j++)
- {
- if (client_fd[j] != 0 && client_fd[j] != sd)
- {
- send(client_fd[j], buffer, strlen(buffer), 0);
- }
- }
- }
- }
- }
- }
- close(server_fd);
- // return 0;
- }
|