inetsrv.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /* Byte Stream Connection Server Example
  2. Copyright (C) 1991-2026 Free Software Foundation, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, see <https://www.gnu.org/licenses/>.
  13. */
  14. #include <arpa/inet.h>
  15. #include <stdio.h>
  16. #include <errno.h>
  17. #include <stdlib.h>
  18. #include <unistd.h>
  19. #include <sys/types.h>
  20. #include <sys/socket.h>
  21. #include <netinet/in.h>
  22. #include <netdb.h>
  23. #define PORT 5555
  24. #define MAXMSG 512
  25. int
  26. read_from_client (int filedes)
  27. {
  28. char buffer[MAXMSG];
  29. int nbytes;
  30. nbytes = read (filedes, buffer, MAXMSG);
  31. if (nbytes < 0)
  32. {
  33. /* Read error. */
  34. perror ("read");
  35. exit (EXIT_FAILURE);
  36. }
  37. else if (nbytes == 0)
  38. /* End-of-file. */
  39. return -1;
  40. else
  41. {
  42. /* Data read. */
  43. fprintf (stderr, "Server: got message: `%s'\n", buffer);
  44. return 0;
  45. }
  46. }
  47. int
  48. main (void)
  49. {
  50. extern int make_socket (uint16_t port);
  51. int sock;
  52. fd_set active_fd_set, read_fd_set;
  53. int i;
  54. struct sockaddr_in clientname;
  55. socklen_t size;
  56. /* Create the socket and set it up to accept connections. */
  57. sock = make_socket (PORT);
  58. if (listen (sock, 1) < 0)
  59. {
  60. perror ("listen");
  61. exit (EXIT_FAILURE);
  62. }
  63. /* Initialize the set of active sockets. */
  64. FD_ZERO (&active_fd_set);
  65. FD_SET (sock, &active_fd_set);
  66. while (1)
  67. {
  68. /* Block until input arrives on one or more active sockets. */
  69. read_fd_set = active_fd_set;
  70. if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
  71. {
  72. perror ("select");
  73. exit (EXIT_FAILURE);
  74. }
  75. /* Service all the sockets with input pending. */
  76. for (i = 0; i < FD_SETSIZE; ++i)
  77. if (FD_ISSET (i, &read_fd_set))
  78. {
  79. if (i == sock)
  80. {
  81. /* Connection request on original socket. */
  82. int new;
  83. size = sizeof (clientname);
  84. new = accept (sock,
  85. (struct sockaddr *) &clientname,
  86. &size);
  87. if (new < 0)
  88. {
  89. perror ("accept");
  90. exit (EXIT_FAILURE);
  91. }
  92. fprintf (stderr,
  93. "Server: connect from host %s, port %hd.\n",
  94. inet_ntoa (clientname.sin_addr),
  95. ntohs (clientname.sin_port));
  96. FD_SET (new, &active_fd_set);
  97. }
  98. else
  99. {
  100. /* Data arriving on an already-connected socket. */
  101. if (read_from_client (i) < 0)
  102. {
  103. close (i);
  104. FD_CLR (i, &active_fd_set);
  105. }
  106. }
  107. }
  108. }
  109. }