server_tcp_select.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <sys/types.h>
  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8. #include <arpa/inet.h>
  9. #include <sys/select.h>
  10. #define PORT 5000
  11. #define MAX_CLIENTS 10
  12. #define BUFFER_SIZE 256
  13. void error(const char *msg) {
  14. perror(msg);
  15. exit(1);
  16. }
  17. void main()
  18. {
  19. int server_fd;
  20. int client_fd[MAX_CLIENTS] = {0}; // Array to store client socket descriptors
  21. struct sockaddr_in server, client;
  22. fd_set readfds, copyfds;
  23. int max_fd, new_socket, activity, i, valread, sd;
  24. socklen_t addr_len = sizeof(client);
  25. char buffer[BUFFER_SIZE];
  26. // Create a TCP socket
  27. server_fd = socket(AF_INET, SOCK_STREAM, 0);
  28. if (server_fd < 0)
  29. {
  30. error("Error opening socket.");
  31. }
  32. // Prepare the sockaddr_in structure
  33. server.sin_family = AF_INET;
  34. server.sin_addr.s_addr = INADDR_ANY;
  35. server.sin_port = htons(PORT);
  36. // Allow reuse of addresses
  37. int opt = 1;
  38. setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
  39. // Bind the socket to the port
  40. if (bind(server_fd, (struct sockaddr *)&server, sizeof(server)) < 0)
  41. {
  42. error("Binding failed");
  43. }
  44. // Listen for incoming connections
  45. if (listen(server_fd, 5) < 0)
  46. {
  47. error("Listening failed");
  48. }
  49. printf("Listening on port %d...\n", PORT);
  50. while(1)
  51. {
  52. FD_ZERO(&readfds);
  53. FD_SET(server_fd, &readfds);
  54. max_fd = server_fd;
  55. // Add child sockets to the set
  56. for (i = 0; i < MAX_CLIENTS; i++)
  57. {
  58. sd = client_fd[i];
  59. if (sd > 0)
  60. {
  61. FD_SET(sd, &readfds);
  62. }
  63. if (sd > max_fd)
  64. {
  65. max_fd = sd;
  66. }
  67. }
  68. // Wait for an activity on one of the sockets
  69. activity = select(max_fd + 1, &readfds, NULL, NULL, NULL);
  70. if (activity < 0)
  71. {
  72. error("Select error");
  73. }
  74. // If something happened on the server socket, then it's an incoming connection
  75. if (FD_ISSET(server_fd, &readfds))
  76. {
  77. new_socket = accept(server_fd, (struct sockaddr *)&client, &addr_len);
  78. if (new_socket < 0)
  79. {
  80. error("Accept error");
  81. }
  82. printf("New connection from %s on socket %d\n", inet_ntoa(client.sin_addr), new_socket);
  83. // Add new socket to array of sockets
  84. for (i = 0; i < MAX_CLIENTS; i++)
  85. {
  86. if (client_fd[i] == 0)
  87. {
  88. client_fd[i] = new_socket;
  89. break;
  90. }
  91. }
  92. }
  93. // Check all clients for incoming messages
  94. for (i = 0; i < MAX_CLIENTS; i++)
  95. {
  96. sd = client_fd[i];
  97. if (FD_ISSET(sd, &readfds))
  98. {
  99. // Check if it was for closing, and also read the incoming message
  100. valread = read(sd, buffer, sizeof(buffer));
  101. if (valread > 0)
  102. {
  103. buffer[valread] = '\0'; // Null-terminate the received string
  104. printf("Message from client: %s\n", buffer);
  105. // Broadcast the message to all other clients
  106. for (int j = 0; j < MAX_CLIENTS; j++)
  107. {
  108. if (client_fd[j] != 0 && client_fd[j] != sd)
  109. {
  110. send(client_fd[j], buffer, strlen(buffer), 0);
  111. }
  112. }
  113. }
  114. }
  115. }
  116. }
  117. close(server_fd);
  118. // return 0;
  119. }