网络超时检测

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

实质

阻塞:如果缓冲区或者文件内没有数据,则会一直阻塞下去,直到有数据来为止
非阻塞:在运行函数时,会轮询的观察缓冲区或者文件内有没有数据,有数据,则正常执行,
如果没有数据,则立即返回
超时检测:设定一定的时间,在时间范围之内一直阻塞等待数据的到来,如果时间到时还没
有数据,则立即返回

网络超时检测:当客户端连接到服务器之后,服务器端就会开辟一块空间与客户端进行通信,
如果客户端长时间不与服务器通信,则浪费服务器资源,所以需要超时检测

方法一:

使用setscokopt函数实现网络超时检测

 
#include <sys/socket.h>

int setsockopt(int socket, int level, int option_name,
       const void *option_value, socklen_t option_len);
功能:设置一个套接字的选项
参数:
sockfd:文件描述符
level:协议层次
SOL_SOCKET 套接字层次
optname:选项的名称(套接字层次)
SO_RCVTIMEO 设置接收超时时间
optval:获取到的选项的值
struct timeval                                                                                                   
{
__time_t tv_sec;      	秒
__suseconds_t tv_usec;  微秒
};
optlen:optval的长度
返回值:	
成功:0
失败:-1

方法二:

使用select函数实现网络超时检测,设置select最后的一个参数:注意select调用后会清零超时结构体,需要重新设置时间

#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

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                                                                                                   
{
__time_t tv_sec;      	秒
__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是否在集合里面

方法三:

用alarm闹钟实现网络超时检测
使用alarm设置时间,代码继续往下运行,当时间到达时,会结束整个进程,如果结合信号,当闹钟响时,会触发SIGALRM信号,处理信号处理函数,当信号处理,函数执行完毕,会接着之前的程序继续运行,这一属性称之为自重启属性,如果想实现超时,则需要关闭这一属性。

#include <signal.h>

int sigaction(int signum, const struct sigaction *act,
      struct sigaction *oldact);

功能:
信号处理
参数:
		signum:信号类型
		act:   新的信号行为
		oldact:旧的信号行为
返回值:
成功 0,失败 -1
#if  1
struct sigaction  act;
sigaction(SIGALRM, NULL, &act);
//读   
act.sa_handler = handler;
//改------>信号处理函数
act.sa_flags &= ~SA_RESTART;
--------->防止系统自重启
sigaction(SIGALRM, &act, NULL);//写
#endif

	
		
使用sigaction来修改一个信号的行为
#include <signal.h>

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
功能:获取或者设置一个信号的行为
参数:
		signum:信号
		act:新的行为
		oldact:旧的行为
		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); 没有用
		};
返回值:
		成功: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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值