首页 > 代码库 > 网络超时检测的三种方法

网络超时检测的三种方法

作者:于老师,华清远见嵌入式学院讲师。

网络通信中,很多操作会使得进程阻塞,这时我们要设定时间,到时间后强制返回,避免进程在没有数据的情况下无限阻塞

这里我们总结一下网络超时检测的三种方法:

通过setsockopt设置套接字属性SO_RCVTIMEO

struct timeval t = {5, 0}
          if  (setsockopt(listenfd, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(t)) == -1) {
                    perror("setsockopt");
                    return  -1;
          }
          memset(&peeraddr,  0, sizeof(peeraddr));
          len  = sizeof(peeraddr);
          if  ((connfd = accept(listenfd, (struct sockaddr *)&peeraddr, &len)) == -1)  {
          printf("errno=%d:  %s\n", errno, strerror(errno));
                    if  (errno == EAGAIN) {
                             printf("timeout\n");
                             return  -1;
                    }
         }

二、设定select函数的一个参数实现超时处理

struct timeval t= {3, 0};
          while  (1) {
                    。。。。。。
                    t.tv_sec  = 3;
                    t.tv_usec  = 0;
                    if  ((ret = select(maxfd+1, &rdfs, NULL, NULL, &t)) == -1) {
                             perror("select");
                             return  -1;
                    }
                    。。。。。。
         }

三、设定一个定时器捕捉SIGALRM信号做超时控制

struct sigaction act;
          sigaction(SIGALRM,  NULL, &act); //获取SIGALRM信号的属性
          act.sa_handler  = handler; // 设置SIGALRM信号的处理函数
          sigaction(SIGALRM,  &act, NULL); // 设置SIGALRM信号的属性
          alarm(3); // 定时器设置3秒钟
          while  (1) {
                    if  ((connfd = accept(listenfd, (struct sockaddr *)&peeraddr, &len)) == -1)  {
                             if  (errno == EINTR) {
                                      printf("timeout\n");
                                      return  -1;
                             }
                    }

定时器3秒钟内没有数据到来,内核产生SIGALRM信号中断当前操作。我们知道设置信号捕捉函数可以用signal函数或是sigaction函数。但这里只能使用sigaction函数,因为signal设置的信号处理函数执行完后会重新执行被中断的操作


本文出自 “嵌入式学习天地” 博客,请务必保留此出处http://farsight.blog.51cto.com/1821374/1563349

网络超时检测的三种方法