[C&C++中超时实现]
一般在Linux C/C++中,可以使用:alarm() 设置定时器的方式实现秒级超时,或者:select()、poll()、epoll() 之类的异步复用IO实现毫秒级超时。也可以使用二次封装的异步io库libevent, libev)也能实现。
一、使用alarm中用信号实现超时 秒级超时)
说明:Linux内核connect超时通常为75秒,我们可以设置更小的时间如10秒来提前从connect中返回。这里用使用信号处理机制,调用alarm,超时后产生SIGALRM信号 也可使用select实现)
用 alarym 秒级实现 connect 设置超时代码示例:
- //信号处理函数
- static void connect_alarm(int signo)
- {
- debug_printf("SignalHandler");
- return;
- }
- //alarm超时连接实现
- static void conn_alarm()
- {
- Sigfunc * sigfunc ; //现有信号处理函数
- sigfunc=signal(SIGALRM, connect_alarm); //建立信号处理函数connect_alarm,(如果有)保存现有的信号处理函数
- int timeout = 5;
- //设置闹钟
- if( alarm(timeout)!=0 ){
- //... 闹钟已经设置处理
- }
- //进行连接操作
- if (connect(m_Socket, (struct sockaddr *)&addr, sizeof(addr)) < 0 ) {
- if ( errno == EINTR ) { //如果错误号设置为EINTR,说明超时中断了
- debug_printf("Timeout");
- m_connectionStatus = STATUS_CLOSED;
- errno = ETIMEDOUT; //防止三次握手继续进行
- return ERR_TIMEOUT;
- }
- else {
- debug_printf("Other Err");
- m_connectionStatus = STATUS_CLOSED;
- return ERR_NET_SOCKET;
- }
- }
- alarm(0);//关闭时钟
- signal(SIGALRM, sigfunc); //(如果有)恢复原来的信号处理函数
- return;
- }
//读取数据的超时设置
同样可以为 recv 设置超时,5秒内收不到任何应答就中断
- signal( ... );
- alarm(5);
- recv( ... );
- alarm(0);
- static void sig_alarm(int signo){return;}
当客户端阻塞于读(readline,...)时,如果此时服务器崩了,客户TCP试图从服务器接收一个ACK,持续重传 数据分节,大约要等9分钟才放弃重传,并返回一个错误。因此,在客户读阻塞时,调用超时。
PHP之友评论