TCP/IP协议分为4层,分别为应用层、传输层、网络层、数据链路层,TCP协议在TCP/IP协议族的传输层,它提供一种面向连接的、可靠的字节流服务,服务器和客户端交换数据之前必须先建立一个连接,在此基础之上双方进行通信。但实际中会存在各种问题导致掉线(如有的防火墙会关闭长时间没有数据交换的网络、中间路由器断掉等),对于TCP长连接而言,服务器和客户端在很长一段时间内可能不会进行数据交互,但客户端会随时上传数据,因此该连接必须保持。那么如何检测连接的通断情况呢?本文提供两种思路方法,希望还有其他方法的朋友提出来分享交流。

1、 TCP机制本身提供了一种方法——keepalive机制,在网络空闲一长段时间后底层发出报文,若网络通畅,会收到对端回复的报文,则说明网络通畅,则继续等待空闲一长段时间再发报文,若未收到对端报文则说明网络对端掉线,则每隔一小段时间发送报文,若几次都没有收到对端的报文,则说明对端彻底掉线,本地应用层recv()函数会返回0,则将该套接字关闭。该机制在TCP/IP协议的传输层实现,可以通过应用层设置keepalive的相关参数,代码如下。该方法适合并发服务器检测网络通畅性问题。

int SetTcpKeepalive(int fd, unsigned int start, unsigned int interval, unsigned int count)
{     int keepAlive = 1;     if (fd < 0 || start < 0 || interval < 0 || count < 0)return -1; //启用心跳机制,如果您想关闭,将keepAlive置零即可     if(setsockopt(fd,SOL_SOCKET,SO_KEEPALIVE,(void*)&keepAlive,sizeof(keepAlive)) == -1)     {     perror("setsockopt");     return -1;     }     //启用心跳机制开始到首次心跳侦测包发送之间的空闲时间     if(setsockopt(fd,SOL_TCP,TCP_KEEPIDLE,(void *)&start,sizeof(start)) == -1)     {     perror("setsockopt");     return -1;     }     //两次心跳侦测包之间的间隔时间     if(setsockopt(fd,SOL_TCP,TCP_KEEPINTVL,(void *)&interval,sizeof(interval)) == -1)     {     perror("setsockopt");     return -1;     }     //探测次数,即将几次探测失败判定为TCP断开     if(setsockopt(fd,SOL_TCP,TCP_KEEPCNT,(void *)&count,sizeof(count)) == -1)     {     perror("setsockopt");     return -1;     }     return 0;
}

2、应用层发送心跳包:每隔一段时间向对端发送一个较小的数据包,通知对方自己在线,并传输一些可能必要的数据(如告诉服务器该数据包为心跳包),并且定时检测对端返回的数据,若连续几次在规定时间内均未收到回复,则判断对端掉线,可以做下一步处理。该方法适合用于客户端处理,在应用层开一个线程发送心跳包,本例中只有发送数据包,未做接收数据处理。数据报文如下:

typedef  char  Data;typedef enum {HEART = 0,   //心跳报文头部MSG          //数据报文头部
}Type;typedef struct datapack{Type  type;    //若为心跳报文,buf和len为0Data  buf[32];int   len;
}DataPack;

处理心跳报文的线程函数如下:


void *HeartBeat(void *argc)
{int ret = 0;int cunt = 0;int i = 0;DataPack heart_data;bzero(&heart_data, sizeof(heart_data));heart_data.type = HEART;heart_data.len = 0;printf("start send heartbeat data \n");cunt = 0;while(1){ret = send(cli_fd, &heart_data, sizeof(heart_data), 0);if(ret < 0){cunt ++;if(errno == EPIPE){//服务器关闭,发送数据导致管道破裂//处理流程}if(cunt > 5){printf("server is offline \n");printf("the client is going down \n");exit(0);}close(cli_fd);}delay(3000);}
}

在服务器崩溃以后客户端还调用send()函数会导致管道破裂,该信号的默认处理方式为结束进程, 为了避免进程结束可以调用signal函数忽略掉该信号,如下:

signal(SIGPIPE, SIG_IGN);

本文中若有不足的地方请各位看官提出。

TCP 应用层 心跳包相关推荐

  1. TCP socket心跳包示例程序

    TCP socket心跳包示例程序_xqhrs232的专栏-CSDN博客_setsockopt 心跳包 原文地址::TCP socket心跳包示例程序_神奕的专栏-CSDN博客_tcp心跳包 相关文章 ...

  2. 心跳检测以及应用层心跳包机制设计

    博主联系方式: QQ:1540984562 微信:wxid_nz49532kbh9u22 QQ交流群:892023501(嵌入式方向) QQ交流群:856398158(后端方向) 目录 心跳检测应用场 ...

  3. 游戏服务器心跳包的作用

    游戏服务器心跳包的作用 服务端为什么需要心跳(保活)机制 TCP-Keepalive-HOWTO 闲说HeartBeat心跳包和TCP协议的KeepAlive机制 Socket心跳包机制 心跳包的作用 ...

  4. tcp连接探测Keepalive和心跳包

    采用TCP连接的C/S模式软件,连接的双方在连接空闲状态时,如果任意一方意外崩溃.当机.网线断开或路由器故障,另一方无法得知TCP连接已经失效,除非继续在此连接上发送数据导致错误返回.很多时候,这不是 ...

  5. 闲说HeartBeat心跳包和TCP协议的KeepAlive机制

    很多应用层协议都有HeartBeat机制,通常是客户端每隔一小段时间向服务器发送一个数据包,通知服务器自己仍然在线,并传输一些可能必要的数据.使用心跳包的典型协议是IM,比如QQ/MSN/飞信等协议. ...

  6. TCP协议的KeepAlive机制与HeartBeat心跳包

    原文地址:http://www.nowamagic.net/academy/detail/23350382 心跳包 很多应用层协议都有HeartBeat机制,通常是客户端每隔一小段时间向服务器发送一个 ...

  7. TCP连接的心跳包机制

    文章目录 什么是心跳机制 为什么需要心跳机制? 如何及时有效地检测到另一方的非正常断开 TCP的keeplive保活机制 什么是心跳机制 所谓的心跳包就是(探测性的)数据包,之所以叫心跳包是因为:它像 ...

  8. TCP连接探测中的Keepalive和心跳包

    1. TCP保活的必要性 1) 很多防火墙等对于空闲socket自动关闭 2) 对于非正常断开, 服务器并不能检测到. 为了回收资源, 必须提供一种检测机制. 2. 导致TCP断连的因素 如果网络正常 ...

  9. linux内核协议栈 TCP连接探测中的Keepalive和心跳包使用

    目录 1 TCP保活的必要性 2 导致TCP断连的因素 3 保活的两种方式 3.1 应用层面的心跳机制 3.2 TCP协议自带的保活功能 4 两种方式的优劣性 5 到底选用那种心跳方式? 6 配置 K ...

最新文章

  1. Java项目:校园人力人事资源管理系统(java+Springboot+ssm+mysql+jsp+maven)
  2. ubuntu连有线网 无法连接外网
  3. 动态规划习题,关系式推导和求模技巧
  4. golang mongodb or条件_MongoDB的学习,操作命令详细介绍
  5. powershell 遍历json_使用PowerShell处理JSON字符串
  6. php基础教程(三):变量
  7. Java基础——synchronized
  8. 你应该升级到SQL Server 2005还是SQL Server 2008?
  9. NSURLConnection 下载数据 -- IOS(实例)
  10. Java中布尔值的定义_使用简单的布尔值作为自定义验证器
  11. java16进制取前几位_16位16进制数怎么取前8位和后8位
  12. AtCoder Beginner Contest 137 解题报告(A ~ E)
  13. H2080刷卡门禁一体机使用说明书 誉诚AD281A-T楼宇主机说明书
  14. JAVA实现文本翻译功能_java实现简单的英文文本单词翻译器功能示例
  15. java.security.NoSuchAlgorithmException: SHA256WithRSAandMGF1 Signature not available
  16. C#高级编程——C#扩展方法+接口,定义统一的搜索接口,基于Unity(三)——图文详解加源码
  17. esp32 s3 外部flash和外部psram配置
  18. 程序员真的是吃青春饭的吗?有哪些建议可以给刚入职的程序员?(全是干货)...
  19. 使用tinymce编辑器从word保持原格式复制粘贴的办法
  20. webrequest、httpwebrequest、webclient、HttpClient 四个类的区别?

热门文章

  1. 易驾佳智能机器人教练_用RoboCoach代替驾校教练 易驾佳欲用AI技术改变驾培
  2. android studio 抽屉,Android Studio 的抽屉导航
  3. Android Studio下16进制颜色代码说明
  4. android 抽屉,凌乱了 Android的抽屉到底要不要?
  5. 50 个新酷的 jQuery 插件
  6. 群晖中网络设置错误,导致无法搜寻群晖的IP
  7. AI工具:Anaconda中Jupyter不能import已安装module问题解决
  8. JAVA开发的OA自动化办公系统
  9. 智能交通系统,可以提高通行效率,节约能源,降低空气污染的水平
  10. net.ipv4.tcp_tw_reuse是干嘛的?