46.Linux网络编程 | 您所在的位置:网站首页 › linux网络编程超时时间 › 46.Linux网络编程 |
一.超时引用必要性
在网络通信中,很多操作会使得进程阻塞例如 TCP套接字中的recv/accept/connect UDP套接字中的recvfrom 你也不能一直阻塞着不干活啊, 避免进程在没有数据时无限制地阻塞,所以引入超时检测。 当设定的时间到时,进程从原操作返回继续运行。 二.设置超时的三种方法: 1. 设置socket的属性 SO_RCVTIMEO,我们上面讲的改属性 例: 设置接收超时: struct timeval tout; tout.tv_sec = 5; tout.tv_usec = 0; setsockopt (fd, SOL_SOCKET, SO_RCVTIMEO, &tout, sizeof (struct timeval));
2. 用select检测socket是否’ready’,也是我们学习select学过的。 例: struct fd_set rdfs; struct timeval tv = {5 , 0}; // 设置5秒时间 FD_ZERO(&rdfs); FD_SET(sockfd, &rdfs); if (select(sockfd+1, &rdfs, NULL, NULL, &tv) > 0) //
3. 设置定时器(timer), 捕捉SIGALRM信号,这个在讲信号章节的时候也有说到。 设置一个alarm信号,时间到了触发信号。 void handler(int signo) { return; } struct sigaction act; sigaction(SIGALRM, NULL, &act); act.sa_handler = handler; act.sa_flags &= ~SA_RESTART; //清除掉SIGALRM信号的SA_RESTART sigaction(SIGALRM, &act, NULL); alarm(5); if (recv(,,,) < 0) 设置一个alarm信号,recv一直阻塞等待数据,当5s到来时,产生一个信号,打断recv的阻塞,去处理其他事情。 三.如何在linux中动态检测是否有网络,或者网络中途掉线? 1.应用层,使用心跳检测(客户端每过一段时间就给服务器发一个心跳包,告诉我还活着。) 2.我们的setsockopt属性修改参数中,有个SO_KEEPALIVE 保持连接的属性,它在不修改的情况下默认是2个小时检查一次连接。 int keepAlive = 1; //设定KeepAlive int keepIdle = 5; //开始首次KeepAlive探测前的TCP空闭时间 int keepInterval = 5; //两次KeepAlive探测间的时间间隔 int keepCount = 3; //判定断开前的KeepAlive探测次数 setKeepAlive (newfd, keepAlive, keepIdle, keepInterval, keepCount);//这个函数内部调用了setsockopt函数。 来改变套接字的属性,来完成网络的检测。
这节看着内容不多,但是是非常重要的,超时的应用在我们之后的编程中使用的非常多,灵活的使用可以提高我们代码的执行效率,减少不必要的资源浪费。 |
CopyRight 2018-2019 实验室设备网 版权所有 |