网络超时优化 网络程序中常用的三种心跳机制----服务器端

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

比如,TCP套接字中的read、send、recv、accept、connect等,以及UDP套接字中的recvfrom等。

超时检测的必要性:

—  避免进程在没有数据时无限制地阻塞

—  当设定的时间到时,进程从原操作返回继续运行

网络超时检测(一)

设置socket的属性 SO_RCVTIMEO
 1 /**** 设置socket的属性 SO_RCVTIMEO****/
 2 
 3 //参考代码:
 4 struct timeval tv;
 5 
 6 tv.tv_sec = 5;  //设置5秒时间
 7 tv.tv_usec = 0;
 8 
 9 setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));   //设置接收超时
10 
11 recv() / recvfrom()   //从socket读取数据

网络·超时检测(二)

用select检测socket是否“ready”

 1 struct fd_set rfds;
 2 struct timeval tv = (5, 0);  //设置5秒时间
 3 
 4 FD_ZERO(&rdfs);
 5 FD_SET(sockfd, &rdfs);
 6 
 7 if(select(sockfd+1, &rdfs, NULL, NULL, &tv) > 0)  //socket就绪
 8 {
 9      recv() / recvfrom()    //从socket读取数据  
10 }

网络超时检测(三)

设置定时器(timer),捕捉SIGALRM信号

 1 void handler(int signo)
 2 {
 3      return;  
 4 }
 5 
 6 struct sigaction act;
 7 sigaction(SIGALRM, NULL, &act);
 8 act.sa_handler = handler;  //处理函数
 9 act.sa_flags   &= ~SA_RESTART;  //取反再与-->清除SA_RESTART标识位,系统就不会直接去读数据了。
10 sigaction(SIGALRM, &act, NULL);
11 alarm(5);   //如果recv超过5秒没有信号来,定时器就触发SIGALRM信号,进而打断recv的阻塞
12 if(recv(......) < 0) ....

如何在Linux中动态检查到是否有网络以及网络中途的掉线 / 连接的检查

提示:

1、应用层
心跳检测,详见:网络程序中常用的三种心跳机制----服务器端

2、内核中
·网卡驱动中 2.6内核里面,使能1s的周期性检查定时器
·网卡硬件或者我们通过GPIO,插拔网线时候产生中断,处理相应中断 //立即检测到

心跳检测---方法一

数据交互双方隔一段时间,一方发送一点数据到对方,对方给出特定的应答。如超过设定次数大小的时间内还是没有应答,这时候认为异常

心跳检测---方法二

改变套接字的属性来实现

 1 #include <netinet/tcp.h>//包含了SOL_TCP等宏的定义
 2 void setKeepAlive(int sockfd,int attr_on,socklen_t idle_time,socklen_t interval,socklen_t cnt)
 3 {
 4     setsockopt(sockfd,SOL_SOCKET,SO_KEEPALIVE,(const char *)&attr_on,sizeof(attr_on));
 5     setsockopt(sockfd,SOL_TCP,TCP_KEEPIDLE,(const char *)&idle_time,sizeof(idle_time));
 6     setsockopt(sockfd,SOL_TCP,TCP_KEEPINTVL,(const char *)&interval,sizeof(interval));
 7     setsockopt(sockfd,SOL_TCP,TCP_KEEPCNT,(const char *)&cnt,sizeof(cnt));
 8 }
 9 ......
10 ......
11 /*心跳检测(自动检测套接字连接是否已断开)*/
12 int keepAlive = 1;//设定keepAlive
13 int keepIdle = 5;//开始首次keepAlive探测前的TCP空闲时间
14 int keepInterval = 5;//两次keepAlive探测间的时间间隔
15 int keepCount = 3;//判定断开前的keepAlive探测次数
16 
17 setKeepAlive(newfd,keepAlive,keepIdle,keepInterval,keepCount);
18 ......
19 ......

猜你喜欢

转载自www.cnblogs.com/y4247464/p/12238936.html
今日推荐