TCP客户端判断与服务端断开连接的几种方法

TCP客户端判断与服务端断开连接的几种方法

    • 1、epoll
    • 2、自定义心跳包方式检测
    • 3、keeplive方式检测
    • 4、getsockopt

目前已知的方法有:
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方式检测

利用系统发送心跳包。和上述心跳包检测方式一致
设置三个参数:

  1. tcp_keepalive_time:连接闲置多久开始发keepalive的ack包
  2. tcp_keepalive_probes:发几个ack包不回复才当对方死了
  3. tcp_keepalive_intvl:两个ack包之间间隔多长

4、getsockopt

在应用程序中可以通过调用如下代码来判断连接是否断开

	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/ip,网络,服务器)