目前已知的方法有:
1、epoll(能检测正常的断开连接,事件触发机制,优点是快速,但是插拔网线是检测不到的)
2、自定义心跳包方式检测
3、keeplive方式检测
4、getsockopt
1、epoll
1、相对于select和poll来说,epoll更加灵活,没有描述符限制。epoll使用一个文件描述符管理多个描述符,将用户关系的文件描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间的copy只需一次。
2、在注册epoll的时候主要是监听两类事件(EPOLLIN和EPOLLOUT),这两类事件分别代表着可读和可写。我们可以创建读写回调函数,当检测到对应事件的时候,调用对应的程序。为了检测客户端和服务器已经断开我们需要注册另一类事件(EPOLLRDHUP)。该事件代表的是读关闭,当服务器close的时候,会触发该事件。(注意不能读的意思内核不能再往内核缓冲区中增加新的内容。已经在内核缓冲区中的内容,用户态依然能够读取到。)
2、自定义心跳包方式检测
该方式对于大家都不陌生,说的直白一点就是定时发送心跳包给服务器。如果发送失败或者服务器没有定时回复,则认为连接已经断开。该方式通用、常见并且有效。在一些实时性要求不高的地方推荐这种方式。(基本现在的cs架构都有心跳机制)。但是该方式不适合我上述需求,因为心跳包是有间隔的,有间隔就代表有延时。同时又不能把心跳包设置的太短,这样会增加服务器负荷。
3、keeplive方式检测
利用系统发送心跳包。和上述心跳包检测方式一致
设置三个参数:文章来源:https://www.toymoban.com/news/detail-413351.html
- tcp_keepalive_time:连接闲置多久开始发keepalive的ack包
- tcp_keepalive_probes:发几个ack包不回复才当对方死了
- tcp_keepalive_intvl:两个ack包之间间隔多长
4、getsockopt
在应用程序中可以通过调用如下代码来判断连接是否断开文章来源地址https://www.toymoban.com/news/detail-413351.html
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;
}
到了这里,关于TCP客户端判断与服务端断开连接的几种方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!