当前位置:   article > 正文

select函数_select fd最大值超限怎么处理

select fd最大值超限怎么处理

select函数可以实现非阻塞方式的程序。它能够监视我们需要监视的文件描述符的变化情况——读写或是异常。

**int select(int maxfdp,fd_set readfds,fd_set writefds,fd_set errorfds,struct timevaltimeout);
头文件:#include <sys/select.h>

maxfdp是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1。
readfds是指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的读变化的,即我们关心是否可以从这些文件中读取数据了,如果这个集合中有一个文件可读,select就会返回一个大于0的值,表示有文件可读,如果没有可读的文件,则根据timeout参数再判断是否超时,若超出timeout的时间,select返回0,若发生错误返回负值。可以传入NULL值,表示不关心任何文件的读变化。
writefds是指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的写变化的,即我们关心是否可以向这些文件中写入数据了,如果这个集合中有一个文件可写,select就会返回一个大于0的值,表示有文件可写,如果没有可写的文件,则根据timeout再判断是否超时,若超出timeout的时间,select返回0,若发生错误返回负值。可以传入NULL值,表示不关心任何文件的写变化。
errorfds同上面两个参数的意图,用来监视文件错误异常。
timeout是select的超时时间,这个参数至关重要,它可以使select处于三种状态。
第一:若将NULL以形参传入,即不传入时间结构,就是将select置于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止;
第二:若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值;
第三:timeout的值大于0,这就是等待的超时时间,即select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,返回值同上述。

返回值
负值:select错误;
正值:某些文件可读写或出错;
0:等待超时,没有可读写或错误的文件。

原文链接:https://blog.csdn.net/mayue_web/article/details/89021273

服务器

 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <string.h>
 #include <sys/select.h>
 #include <sys/time.h>
 #include <sys/types.h>
 #include <unistd.h>
 
  #define SIZE   1024
  
 int main()
 {
      int ret;
      int fd[SIZE] = {0};
  
      //创建socket(文件)
      int sockfd = socket(PF_INET, SOCK_STREAM, 0);  
      //IPV4地址族     流式套接字(TCP)  具体的协议类型(默认0)
      if (-1 == sockfd)
      {
          perror("socket");
          exit(1);
      }
  
      int opt = 1;
      setsockopt(sockfd,SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));  
       //设置地址可以被复用(方便调试)

      struct sockaddr_in server_addr;   //保存服务器本身的信息
      struct sockaddr_in client_addr;   //保存客户端的信息
  
      memset(&server_addr, 0, sizeof(server_addr));   //清空结构体
      server_addr.sin_family = PF_INET;    //地址族  同socket第一个参数
      server_addr.sin_port = 7000;         
      //端口号(大于1024 小于65536) 客户地址可以被复用(方便调试)
      //查满手册,包含头文件 man inet_addr
      server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
      //ip地址 ifconfig>    获取  127.0.0.1回环ip(用于测试)
     
      //绑定信息
      ret = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr))    ;
      if (-1 == ret)
      {
          perror("bind");
          exit(1);
      }
  
      //设置监听队列
      ret = listen(sockfd, 10);
      if (-1 == ret)
      {
          perror("listen");
          exit(1);
      }
      
      fd_set readfd, tmpfd;   //集合
      FD_ZERO(&readfd);          //清空集合
      FD_SET(sockfd, &readfd);   //把sockfd添加到集合 
     int maxfd = sockfd;
  
      int length = sizeof(struct sockaddr_in);
      int i;
      char buf[128] = {0};
  
      while (1)
      {
          tmpfd = readfd;    //select每次会清空集合
          ret = select(maxfd + 1, &tmpfd, NULL, NULL, NULL); 
           //最后一个NULL表示阻塞
          if (-1 == ret)
          {
              perror("select");
              exit(1);
          }
  
         if (FD_ISSET(sockfd, &tmpfd))   //判断是否有客户端发起连接
         {
              printf("有客户端发起连接...\n");
              for (i = 0; i < SIZE; i++)
              { 
                  if (0 == fd[i])
                  {
                      break;
                  } 
              }
              fd[i] = accept(sockfd, (struct sockaddr *)&client_addr, &length)    ;   
              if (-1 == fd[i])
              { 
                  perror("accept");
                  exit(1);
              }
              printf("接受客户端%d的连接!\n", fd[i]);
  
              if (fd[i] > maxfd)
              {
                  maxfd = fd[i];
              }
              FD_SET(fd[i], &readfd);
          } 
         else     //有客户端发消息
         {
             for (i = 0; i < SIZE; i++)
             {
                 if (FD_ISSET(fd[i], &tmpfd))  //判断哪个文件描述符可读
                 {
                     ret = recv(fd[i], buf, sizeof(buf), 0);
                     if (-1 == ret)
                    {
                         perror("recv");
                         exit(1);
                     }
                     if (0 == ret)
                     {
                         printf("客户端%d异常下线\n", fd[i]);
                         close(fd[i]);   //关闭TCP连接
                         FD_CLR(fd[i], &readfd);       //从集合中清除
                         fd[i] = 0;
                         break;
                    }
                    if (!strcmp(buf, "bye"))
                     {
                         printf("客户端%d下线!\n", fd[i]);
                         close(fd[i]);                 //关闭TCP连接
                         FD_CLR(fd[i], &readfd);       //从集合中清除
                         fd[i] = 0;
                         break;
                     }
                     printf("收到%d客户端消息%s\n", fd[i], buf);
                     memset(buf, 0, sizeof(buf));
                     break;
                 }
             }
          }
     }
 
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139

客户端

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
      
 int main() 
 {   
     int sockfd = socket(PF_INET, SOCK_STREAM, 0)
     if (-1 == sockfd)
     {
          perror("socket");
          exit(1);
      }
      
      //客户端向服务器发起连接
      struct sockaddr_in server_addr;
      memset(&server_addr, 0, sizeof(server_addr));
      //跟服务器保持一致
      server_addr.sin_family = PF_INET;
      server_addr.sin_port = 7000;
      server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
 
      int ret = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
      if (-1 == ret)
      {
          perror("connect");
          exit(1);
      }
 
      char buf[128] = {0};
      while (1)
      {
          scanf("%s", buf);
          ret = send(sockfd, buf, strlen(buf), 0); //write
          if (-1 == ret)
         {
              perror("send");
              exit(1);
         }
         if (!strcmp(buf, "bye"))
         {
              break;
          }
      }
      close(sockfd);   //关闭TCP连接
 
      return 0;
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/675155
推荐阅读
相关标签
  

闽ICP备14008679号