linux select socket 例子

/*server.c*/
#include <signal.h>
#include <sys/wait.h>
#include "inet.h"
#include <stdlib.h>
int init_ser (int);
int
max (int a, int b)
{
  int themax;

  if (a > b)
    themax = a;
  else
    themax = b;
  return themax;
}

void
set_name (char *line, char *name)
{
  strcpy (name, &line[1]);
  sprintf (line, "%s join the room\n", name);
}

void
add_name (char *line, char *name)
{
  char theline[MAX_LINE];

  strcpy (theline, name);
  strcat (theline, " : ");
  strcat (theline, line);
  strcpy (line, theline);
}

int
user_free (int user_link[MAX_CLIENT])
{
  int i = 0;

  while ((user_link[i] != 0) && (i < MAX_CLIENT))
    i++;
  if (i == MAX_CLIENT)
    return (-1);
  return (i);
}

void
add_sockset (fd_set * sockset, int sockfd, int *user_link, int *userfd)
{
  int i;

  FD_ZERO (sockset);
  FD_SET (sockfd, sockset);
  for (i = 0; i < MAX_CLIENT; i++)
    {
      if (user_link[i] == 1)
    {
      FD_SET (userfd[i], sockset);
    }
    }
}

int
main (void)
{
  int sockfd;
  int new_sockfd;
  int user_link[MAX_CLIENT];
  int userfd[MAX_CLIENT];
  char username[MAX_CLIENT][MAX_NAME];
  char line[MAX_LINE];
  int userCount;
  unsigned int cli_len;
  struct sockaddr_in cli_addr;
  FILE *file;
  int port = 1234;
  int length, i, j;
  fd_set sockset;
  int maxfd = 0;

  printf ("%d \n", port);
  sockfd = init_ser (port);

  if (sockfd == 0)
    {
      printf ("Init server socket error\n");
      fflush (stdout);
      exit (1);
    }                //Socket init done   

  listen (sockfd, MAX_CLIENT);
  cli_len = sizeof (cli_addr);
  for (i = 0; i < MAX_CLIENT; i++)
    {
      user_link[i] = 0;
      username[i][0] = '\0';
    }
  userCount = 0;
  FD_ZERO (&sockset);
  FD_SET (sockfd, &sockset);
  maxfd = max (maxfd, sockfd + 1);

  for (;;)
    {
      select (maxfd, &sockset, NULL, NULL, NULL);
      if (FD_ISSET (sockfd, &sockset)
      && (userCount = user_free (user_link)) >= 0)
    {
      new_sockfd = accept (sockfd, (struct sockaddr *) &cli_addr,
                   &cli_len);
      if (new_sockfd == 0)
        {
          user_link[userCount] = 0;
          printf ("acc error\n");
        }
      else
        {
          printf ("accept %d\n", new_sockfd);
          user_link[userCount] = 1;
          userfd[userCount] = new_sockfd;
          FD_SET (new_sockfd, &sockset);
          maxfd = max (maxfd, new_sockfd + 1);
        }
    }            // if userCount >= 0   

      int ifd = 0;
      for (i = 0; i < MAX_CLIENT; i++)
    {
      if ((user_link[i] == 1) && (FD_ISSET (userfd[i], &sockset)))
        {
          memset (line, 0, MAX_LINE);
          length = recv (userfd[i], line, MAX_LINE, 0);
          ifd++;        //同时有效的fd

          if (length == 0)
        {        // socket is closed.   
          user_link[i] = 0;
          username[i][0] = '\0';
          FD_CLR (userfd[i], &sockset);
        }
          else if (length > 0)
        {
          line[length] = '\0';
          printf ("[%d]%s\n", userfd[i], line);

          if ((line[0] == '/') && (username[i][0] == '\0'))
            {
              set_name (line, username[i]);
            }
          else
            {
              add_name (line, username[i]);
            }
//给其他client发信息
          for (j = 0; j < MAX_CLIENT; j++)
            {
              if ((j != i) && (user_link[j] == 1))
            {
              send (userfd[j], line, strlen (line), 0);
            }
            }

        }        // length >0   
        }            // user_link[i] == 1   
    }            // for                   
      add_sockset (&sockset, sockfd, user_link, userfd);

      if (ifd > 1)
    {
      printf
        ("*************************************************************ifd = %d\n",
         ifd);
    }
    }                // for           


  return 0;
}

int
init_ser (int port)
//If success, return sockfd, else return 0   
{

  int SERV_TCP_PORT;
  int sockfd;
  struct sockaddr_in serv_addr;

  SERV_TCP_PORT = port;

  if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
    {
      perror ("socket:");
      printf ("server:can`t open stream socker.\n");
      fflush (stdout);
      return (0);
    }

  bzero ((char *) &serv_addr, sizeof (serv_addr));
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = htonl (INADDR_ANY);
  serv_addr.sin_port = htons (SERV_TCP_PORT);
  int yes = 1;
  setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof (int));
  if (bind (sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0)
    {
      perror ("bind:");
      printf ("server: can`t bind local address\n");
      fflush (stdout);
      return (0);
    }
  return (sockfd);        //successful.   
}
posted @ 2012-09-05 16:47  ahuo  阅读(2728)  评论(0编辑  收藏  举报