• 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.   
    }
  • 相关阅读:
    在ASP.NET MVC中使用Redis
    学生管理系统(SSM简易版)总结
    springmvc缓存和mybatis缓存
    解决.NET Web API生成的Help无Controller说明&服务端接收不到请求
    ASP.NET MVC]WebAPI应用支持HTTPS的经验总结
    23 Flutter官方推荐的状态管理库provider的使用
    22 Flutter仿京东商城项目 inappbrowser 加载商品详情、保持页面状态、以及实现属性筛选业务逻辑
    21 Flutter仿京东商城项目 商品详情 请求接口渲染数据 商品属性数据渲染
    16Flutter中的路由 基本路由 基本路由跳转传值(上)
    20 Flutter仿京东商城项目 商品详情 底部弹出筛选属性 以及筛选属性页面布局
  • 原文地址:https://www.cnblogs.com/ahuo/p/2672161.html
Copyright © 2020-2023  润新知