网络中的超时检测!

在网络通信中,很多操作会使得进程阻塞

   1.TCP套接字中的recv/accept/connect

   2.UDP套接字中的recvfrom

超时检测的必要性
   1.避免进程在没有数据时无限制地阻塞
   2.当设定的时间到达时,进程会从原操作返回继续运行

以下是网络超时检测的3种设置方法

  1-- 使用setsockopt 进行超时设置
    struct timeval
    {
     __time_t tv_sec;        /* Seconds.  */  秒
     __suseconds_t tv_usec;  /* Microseconds.  */ 微 
                          };

     
    struct timeval  tv;
    tv.tv_sec = 5;
    tv.tv_usec = 0;
    
   设置超时检测
    if(setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0){
      err_log("fail to setsockopt");
    }

  2-- 使用select 函数实现超时检测
    struct timeval {
     long    tv_sec;         /* seconds */
     long    tv_usec;        /* microseconds */
    };

   int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
   功能:允许一个进程监听多个文件描述符集合,阻塞等待,直到有一个或者多个文件描述符资源准备就绪,那么函数立刻返回。
   参数:nfds       最大的文件描述符加1
         readfds    读文件描述符集合
         writefds   写文件描述符集合
         exceptfds  异常的文件描述符集合
         timeout    如果设置为NULL,则一直阻塞等待
   返回值:成功  timeout 为 NULL 时 ,已经准备就绪的文件描述符的个数
                 timeout 不为NULL时 ,时间到达之前,有文件描述符准备就绪,那                  么返回准备就绪的文件描述符的个数时间到达之前,没有文件描述符  准备就绪那么返回0
           出错   -1
     
   注意:每次select之后成功之后,都会将集合中没有准备就绪的文件
      描述符给清楚掉,所以需要每次重新添加 

struct timeval  tv;

    tv.tv_sec = 5;

        tv.tv_usec = 0;                                                         ret = select(maxfd+1, &readfds, NULL, NULL, &tv);
   注意:每次调用select 函数之前,都应该对tv进行重新赋值

  3-- 使用alarm 定时器 ,实现超时检测
   int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
   功能:注册一个信号,设置信号的属性信息
   参数: signum  信号,不能是 SIGKILL , SIGSTOP
        act     信号新的属性行为
          oldact  信号当前的属性行为
   返回值: 成功 0

    出错 -1

   struct sigaction {
    void     (*sa_handler)(int);  // 信号处理函数
    void     (*sa_sigaction)(int, siginfo_t *, void *);
    sigset_t   sa_mask;
    int        sa_flags;  // SA_RESTART 系统调用的自重启属性。
    void     (*sa_restorer)(void); 
   };
    
   struct sigaction act;
  
   // 注册闹钟信号
   sigaction(SIGALRM, NULL, &act);
    
   act.sa_handler = handler; // 设置信号处理函数
   act.sa_flags &= ~SA_RESTART; //设置自重启属性为假
   
   sigaction(SIGALRM, &act, NULL);
  
   alarm(5);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值