赞
踩
目前已知的方法有:
1、epoll(能检测正常的断开连接,事件触发机制,优点是快速,但是插拔网线是检测不到的)
2、自定义心跳包方式检测
3、keeplive方式检测
4、getsockopt
1、相对于select和poll来说,epoll更加灵活,没有描述符限制。epoll使用一个文件描述符管理多个描述符,将用户关系的文件描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间的copy只需一次。
2、在注册epoll的时候主要是监听两类事件(EPOLLIN和EPOLLOUT),这两类事件分别代表着可读和可写。我们可以创建读写回调函数,当检测到对应事件的时候,调用对应的程序。为了检测客户端和服务器已经断开我们需要注册另一类事件(EPOLLRDHUP)。该事件代表的是读关闭,当服务器close的时候,会触发该事件。(注意不能读的意思内核不能再往内核缓冲区中增加新的内容。已经在内核缓冲区中的内容,用户态依然能够读取到。)
该方式对于大家都不陌生,说的直白一点就是定时发送心跳包给服务器。如果发送失败或者服务器没有定时回复,则认为连接已经断开。该方式通用、常见并且有效。在一些实时性要求不高的地方推荐这种方式。(基本现在的cs架构都有心跳机制)。但是该方式不适合我上述需求,因为心跳包是有间隔的,有间隔就代表有延时。同时又不能把心跳包设置的太短,这样会增加服务器负荷。
利用系统发送心跳包。和上述心跳包检测方式一致
设置三个参数:
- tcp_keepalive_time:连接闲置多久开始发keepalive的ack包
- tcp_keepalive_probes:发几个ack包不回复才当对方死了
- tcp_keepalive_intvl:两个ack包之间间隔多长
在应用程序中可以通过调用如下代码来判断连接是否断开
getsockopt(g_fd, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len);
if ((info.tcpi_state == TCP_ESTABLISHED)) //检测通信是否还处于建立连接的状态
{
// myprintf("socket connected\n");
return 1;
}
else
{
printf("===========socket disconnected");
// myprintf("socket disconnected\n");
return 0;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。