简单的几种网络超时检测
来源:互联网 发布:监控上显示无网络视频 编辑:程序博客网 时间:2024/05/16 13:43
【1】网络超时检测的定义
在网络通信中,很多操作会使得进程阻塞
TCP套接字中的recv/accept
UDP套接字中的recvfrom
超时检测的必要性
避免进程在没有数据时无限制地阻塞
当设定的时间到时,进程从原操作返回继续运行
【2】实质
阻塞函数,当缓冲区或者文件里面没有数据写入,则会一直阻塞直到有数据为止。
非阻塞,及时缓冲区或者文件里面没有数据,也会立即返回,接着往下执行 超时检测,设定一定的时间,在时间范围之内,一直阻塞等待数据的写入,如果时间到时还没有数据,则立即返回,变成非阻塞状态
网络超时检测,当客户端连接服务器,服务器端会开辟一块空间与客户端进行通信,如果客户端在连接之后不与服务器进行通信,则会浪费服务器资源,所以使用超时 将其断开连接,节省服务器资源
【3】方法1:使用setsockopt实现网络超时检测
int setsockopt(int socket, int level, int option_name, const void *option_value, socklen_t option_len);
功能:设置套接字的选项
参数:
socket:文件描述符
level:协议层次
SOL_SOCKET 套接字层次
option_name:选项的名称(套接字层次)
SO_RCVTIMEO 设置接收超时时间
option_value:设置的选项的值
struct timeval {
__kernel_time_t tv_sec; 秒
__kernel_suseconds_t tv_usec; 微秒
};
option_len:value的长度
返回值:
成功:0
失败:-1
使用setsockopt设置的超时时间,设置一次,永久有效。对所有和网络相关的阻塞函数有效
定义结构体变量,并设置超时检测时间5秒
struct timeval time_out;time_out.tv_sec=5;time_out.tv_usec=0;if(setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &time_out, sizeof(time_out)) < 0){ perror("fail to setsockopt");}
while(1)
{
//阻塞等待客户端的连接
if((acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &addrlen)) < 0) { //printf("errno = %d\n", errno);
//超时之后返回的错误码是11。
if(errno == 11) {
//超时打印 printf("连接超时...\n"); } else { perror("fail to accept"); }
}
【4】方法二:使用select函数实现网络超时检测
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
功能:同步一个io操作,允许一个程序处理多个文件描述符,阻塞等待文件描述符准备就绪,如果有一个或者多
个文件描述符准备就绪,则函数立即返回,并执行相应的io操作
参数:
nfds:最大的文件描述符加1
readfds:读文件描述符集合
writefds:写文件描述符集合
exceptfds:其他或者异常的文件描述符集合
timeout:超时
struct timeval { __kernel_time_t tv_sec; 秒
__kernel_suseconds_t tv_usec; 微秒
};
0 非阻塞
NULL 阻塞
返回值:
成功:准备就绪的文件描述符的个数
失败:-1
void FD_ZERO(fd_set *set);
清空一个集合set
void FD_SET(int fd, fd_set *set);
将文件描述符fd添加到集合set里面
void FD_CLR(int fd, fd_set *set);
将文件描述符fd从集合set里面移除
int FD_ISSET(int fd, fd_set *set);
判断文件描述符fd是否在集合set里面
该函数也是永久有效
fd_set readfds;
int maxfd,ret,i;
struct timeval time_out;
//第一步清空集合
FD_ZERO(&readfds);
//第二步将需要的文件描述符添加到集合里
FD_SET(sockfd,&readfds);
maxfd=sockfd; //当前最大描述符值
while(1)
{
time_out.tv_sec = 5; time_out.tv_usec = 0;
//调用select函数阻塞等待文件描述符准备就绪 if((ret = select(maxfd + 1, &tempfds, NULL, NULL, &time_out)) < 0) { errlog("fail to select"); }
//返回值为0时代表超时 else if(ret == 0) { printf("time out...\n"); }
}
【5】方法3:使用alarm闹钟实现网络超时检测
alarm闹钟,当设定一定个的时间之后,代码接着往下运行,当时间到达时候,会退出进程如果结合信号,当闹钟响时,会触发SIGALRM信号,执行信号处理函数,当信号处理函数执行完毕,会接着刚才的代码继续执行,这一属性,称之为自重启属性,如果想实现网络超时检测,需要关闭这一属性
使用sigaction函数设置信号的行为
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
功能:获取或者修改一个信号的行为
参数:
signum:信号
act:新的行为
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); 没有用
};
oldact:旧的行为
返回值:
成功:0
失败:-1
//第一步:读取信号的行为 struct sigaction act;
if(sigaction(SIGALRM, NULL, &act) < 0) { perror("fail to sigaction"); return -1; }
//第二步:修改信号的行为 act.sa_handler = handler; act.sa_flags = act.sa_flags & (~SA_RESTART);
//第三步:将新的行为写回去 if(sigaction(SIGALRM, &act, NULL) < 0) { perror("fail to sigaction"); return -1; }
while(1) { alarm(5); //定时5秒 //阻塞等待客户端的连接请求 if((acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &addrlen)) < 0) { //printf("errno = %d\n", errno);
//延时错误码为4
if(errno == 4) { printf("连接超时...\n"); } else { errlog("fail to accept"); } }
- 简单的几种网络超时检测
- 网络超时检测的三种方法
- 网络超时检测的方法
- 简单几招模拟网络超时情况
- 网络中的超时检测!
- 检测TCP网络断开的几种情况
- 网络编程中的超时检测
- 网络编程中的超时检测
- 网络编程中的超时检测
- 网络编程中的超时检测
- 网络编程中的超时检测
- 网络编程中的超时检测
- 网络编程中的超时检测
- 网络超时检测-setsockopt()
- 【Linux网络编程】超时检测
- 网络编程中的超时检测
- 网络检测的简单方法
- 设置Session超时的几种方式
- Spring印象
- 【Tiff】Matlab读取Tiff显示(控制颜色)
- Python基础(二)
- web.xml中freemarker配置文件
- [HDU-5934] BOMB
- 简单的几种网络超时检测
- Eclipse中配置好Tomcat后在Eclipse里能打开网页在外部的浏览器打不开
- 03 MPI数据类型的匹配和数据类型的转换
- 机器学习面试需要准备啥
- 使用JDBC进行后台登录和注册操作
- java基础--一个简单的记事本
- Python 第三方库(requests)的使用(转)
- 使用Mybatis实现数据库一对多查询
- Day14_Java_作业