• Select模式和超时


     1      fd_set rset;
     2         FD_ZERO(&rset);
     3 
     4         int nready;
     5         int maxfd;
     6         int fd_stdin = fileno(stdin);
     7         if(fd_stdin > sock)
     8         {
     9                 maxfd = fd_stdin;
    10         }
    11         else
    12         {
    13                 maxfd = sock;
    14         }
    15 
    16         char sendbuf[1024] = { 0 };
    17         char recvbuf[1024] = { 0 };
    18         while(1)
    19         {
    20                 FD_SET(fd_stdin,&rset);
    21                 FD_SET(sock,&rset);
    22                 nready = select(maxfd+1,&rset,NULL,NULL,NULL);
    23                 if(nready == -1)
    24                         ERR_EXIT("select");
    25                 if(nready == 0)
    26                         continue;
    27 
    28                 if(FD_ISSET(sock,&rset))
    29                 {
    30 
    31                         int ret = readline(sock,recvbuf,sizeof(sendbuf));
    32                         if(ret == -1)
    33                                 ERR_EXIT("readn");
    34                         else if(ret ==  0)
    35                         {
    36                                 printf("server close");
    37                                 break;
    38                         }
    39 
    40                         fputs(recvbuf,stdout);
    41                         memset(sendbuf,0, sizeof(sendbuf));
    42                         memset(recvbuf,0, sizeof(recvbuf));
    43                 }
    44 
    45                 if(FD_ISSET(fd_stdin,&rset))
    46                 {
    47                         if(fgets(sendbuf,sizeof(sendbuf),stdin) == NULL)
    48                                 break;
    49                         writen(sock,sendbuf,strlen(sendbuf));
    50                 }
    51         }
    52         close(sock);
    View Code
    • void FD_CLR(int fd,fd_set *set);
    • int FD_ISSET(int fd,fd_set *set);
    • void FD_SET(int fd,fd_set *set);
    • void FD_ZERO(fd_set *set);
    • select的超时
      •   
          1 //读超时
          2 int read_timeout(int fd,unsigned int wait_seconds)
          3 {
          4     int ret = 0;
          5     if(wait_seconds > 0)
          6     {
          7         fd_set read_fdset;
          8         struct timeval timeout;
          9         
         10         FD_ZERO(&read_fdset);
         11         FD_SET(fd,&read_fdset);
         12         
         13         timeout.tv_sec = wait_seconds;
         14         timeout.tv_usec = 0;
         15         do
         16         {
         17             ret = select(fd+1,&read_fdset,NULL,NULL,&timeout);
         18         }while(ret < 0 && errno == EINTR)
         19 
         20         if(ret == 0)
         21         {
         22             ret = -1;
         23             errno = ETIMEDOUT;
         24         }
         25         else if(ret == 1)
         26             ret = 0;
         27     }
         28     return ret;
         29 }
         30 
         31 
         32 //接收超时
         33 int accept_timeout(int fd,struct sockaddr_in *addr,unsigned int wait_seconds)
         34 {
         35     int ret;
         36     socklen_t addrlen = sizeof(struct sockaddr_in);
         37     
         38     if(wait_seconds > 0)
         39     {
         40         fd_set accept_fdset;
         41         struct timeval timeout;
         42         FD_ZERO(&accept_fdset);
         43         FD_SET(fd,&accept_fdset);
         44         timeout.tv_sec = wait_seconds;
         45         timeout.tv_usec = 0;
         46         do
         47         {
         48             ret = select(fd+1,&accept_fdset,NULL,NULL,&timeout);
         49         }while(ret < 0 && errno == EINTR)
         50         
         51         if(ret == -1)
         52             return -1;
         53         else if(ret == 0)
         54         {
         55             errno = ETIMEDOUT;
         56             return -1;
         57         }
         58     }
         59     if(addr != NULL)
         60         ret = accept(fd,(struct sockaddr*)addr,&addrlen);
         61     else
         62         ret = accept(fd,NULL,NULL);
         63     if(ret == -1)
         64         ERR_EXIT("accept");
         65     return ret;
         66 }
         67 
         68 void activate_nonblock(int fd)
         69 {
         70     int ret;
         71     int flags = fcntl(fd,F_GETFL);
         72     if(flags == -1)
         73         ERR_EXIT("fcntl");
         74     flags |= O_NONBLOCK;
         75     ret = fcntl(fd,F_SETFL,flags);
         76     if(ret == -1)
         77         ERR_EXIT("fcntl");
         78 }
         79 
         80 void deactivate_nonblock(int fd)
         81 {
         82     int ret;
         83     int flags = fcntl(fd,F_GETFL);
         84     if(flags == -1)
         85         ERR_EXIT("fcntl");
         86     flags &~ O_NONBLOCK;
         87     ret = fcntl(fd,F_SETFL,flags);
         88     if(ret == -1)
         89         ERR_EXIT("fcntl");
         90 }
         91 
         92 //连接超时
         93 int connect_timeout(int fd,struct sockaddr_in *addr, unsigned int wait_seconds)
         94 {
         95     int ret;
         96     socklen_t addrlen = sizeof(struct sockaddr_in);
         97 
         98     if(wait_seconds > 0)
         99         activat_nonblock(fd);
        100     
        101     ret = connect(fd,(struct sockaddr*)addr,addrlen);
        102     if(ret < 0 && errno == EINPROGRESS)
        103     {
        104         fd_set connect_fdset;
        105         struct timeval timeout;
        106         FD_ZERO(&connect_fdset);
        107         FD_SET(fd,&connect_fdset);
        108         timeout.tv_sec = wait_seconds;
        109         timeout.tv_usec = 0;
        110         do
        111         {
        112             ret = select(fd+1,NULL,&connect_fdset,NULL,&timeout);
        113         }while(ret < 0 && errno == EINTR)
        114         if(ret == 0)
        115         {
        116             ret = -1;
        117             errno = ETIMEDOUT;
        118         }
        119         else if(ret < 0)
        120             return -1;
        121         else if(ret == 1)
        122         {
        123             int err;
        124             socklen_t socklen = sizeof(err);
        125             int sockoptret = getsockopt(fd,SOL_SOCKET,SO_ERROR,&err,&socklen);
        126             if(sockoptret == -1)
        127             {
        128                 return -1;
        129             }
        130             if(err == 0)
        131                 ret = 0;
        132             else
        133             {
        134                 errno = err;
        135                 ret = -1;
        136             }
        137         }
        138     }
        139 
        140     if(wait_seconds > 0)
        141     {
        142         deactivate_nonblock(fd);
        143     }
        144     return ret;
        145 }
        View Code
    作者:长风 Email:844064492@qq.com QQ群:607717453 Git:https://github.com/zhaohu19910409Dz 开源项目:https://github.com/OriginMEK/MEK 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利. 感谢您的阅读。如果觉得有用的就请各位大神高抬贵手“推荐一下”吧!你的精神支持是博主强大的写作动力。 如果觉得我的博客有意思,欢迎点击首页左上角的“+加关注”按钮关注我!
  • 相关阅读:
    Flink 源码阅读环境搭建并调试 Flink-Clients 模块
    阅读 Flink 源码前必会的知识 SPI 和 Classloader
    如何 debug hive 源码,知其然知其所以然
    Flink SQL 核心概念剖析与编程案例实战
    Apache Flink 如何正确处理实时计算场景中的乱序数据
    Flink 编程接口
    Flink JobManager 和 TaskManager 原理
    一文带你了解 Flink 的基本组件栈
    flink有什么优势值得大家这么热衷
    实时计算数据架构的演变
  • 原文地址:https://www.cnblogs.com/zhaohu/p/8972315.html
Copyright © 2020-2023  润新知