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