摘自:https://blog.csdn.net/bjrxyz/article/details/71076442

TCP新手误区–心跳的意义

背景

最近面试了很多的学生,发现很多TCP的新手对于TCP的使用有一些误区,而这些坑也是当初我曾经疑惑过得地方。网上很少有文章对这些问题有过详细的解析,即是有也只是直接给出结论和做法,没有人将其中的来龙去脉讲解清楚,所以我将这些问题的来龙去脉在这一系列的文章中讲述出来,希望能让广大TCP的新手避开这些坑。

问题

我面试时经常会问的一个问题是当TCP两端A、B建立了连接后,如果一端拔掉网线或者拔掉电源,那么另一端能够收到通知吗? 
答案是不会,但是只有少数人能够正确的回答这个问题。

原因

TCP是一种有连接的协议,但是这个连接并不是指有一条实际的电路,而是一种虚拟的电路。TCP的建立连接和断开连接都是通过发送数据实现的,也就是我们常说的三次握手、四次挥手。TCP两端保存了一种数据的状态,就代表这种连接,TCP两端之间的路由设备只是将数据转发到目的地,并不知道这些数据实际代表了什么含义,也并没有在其中保存任何的状态信息,也就是说中间的路由设备没有什么连接的概念,只是将数据转发到目的地,只有数据的发送者和接受者两端真正的知道传输的数据代表着一条连接。

但是这就说明了一点,如果不发送数据那么是无法断开连接的。正常情况下当TCP的一端A调用了SOCKET的close或者进程结束,操作系统就会按照TCP协议发送FIN数据报文。B端收到后就会断开连接。但是当出现了上文所说的异常情况时:被拔掉网线或者断掉电源,总结起来就是没有机会发出断开的FIN数据报文。那么和A直连的路由设备虽然知道A设备已经断开了,但是路由设备并没有保存连接的状态信息,所以路由设备也就不可能去通知B端A端的断开。而B端没有收到断开的数据报文就会依然保持连接。所以A端拔掉网线或者断掉电源后B端是没办法收到断开连接的通知的。

解决方案

保持连接并不是毫无代价的,如果这种异常断开的连接有很多,那么势必会耗费大量的资源,必须要想办法检测出这种异常连接。 
检测的方法很简单,只要让B端主动通过这个连接向A端继续发送数据即可。上文说过,A端异常断开后,和A端直接连接的路由器是知道的。当B端发送的数据经过转发后到达这个路由器后,必然最终会返回B端一个目的不可达。此时B端立刻就会知道这条连接其实已经异常断开了。 
但是B端不可能知道什么时候会出现这种异常,所以B端必须定时发送数据来检测连接是否异常断开。数据的内容无关紧要,任何数据都能达到这个效果。这个数据就是我们经常在TCP编程中所说的心跳。

KEEP_ALIVE

TCP协议本身就提供了一种这样的机制来探测对端的存活。TCP协议有一个KEEP_LIVE开关,只要打开这个开关就会定时发送一些数据长度为零的探测心跳包,发送的频率和次数都可以设置,具体的方法在网上搜索tcp keepalive即可,网上有很多文章,这里不再赘述。

应用层心跳

除了使用TCP协议本身的保活开关机制,还可以在应用层主动发送心跳数据包,那么在应用层主动发送心跳数据包的方式和TCP协议本身的保活机制有什么区别呢?

  • 应用层的心跳数据包会耗费更多的带宽,因为TCP协议的保活机制发送的是数据长度为零心跳包,而应用层的心跳数据包长度则必然会大于0。
  • 应用层的心跳数据包可以带一些应用所需要的数据,随应用自己控制,而TCP协议的保活机制则是对于应用层透明的,无法利用心跳携带数据。

双向心跳

那么是否只是一端向另一端发送心跳就行了呢?显然不行。因为两端都有可能发生异常断开的情况。所以TCP连接的两端必须都向对端发送心跳。

总结

TCP中不使用心跳通常来说并没有什么问题,但是一旦遇到了连接异常断开,那么就会出现问题。所以任何一个完善的TCP应用都应该使用心跳。

TCP心跳的意义的更多相关文章

  1. tcp/心跳包

    1,http://blog.csdn.net/yuzhiyuxia/article/details/7857508 心跳包就是在客户端和服务器间定时通知对方自己状态的一个自己定义的命令字,按照一定的时 ...

  2. TCP心跳包

    所谓的心跳包就是客户端定时放送简单的信息给服务器端,告诉它我还在而已.代码就是每 隔几分钟发送一个固定信息给服务器端,服务器端回复一个固定信息.如果服务器端几分钟后没有收到客户端信息则视客户端断开.比 ...

  3. TCP心跳 | TCP keepAlive(转)

    应用层对于每个socket采用如下函数来开启 keepalive机制,其参数将采用系统上述配置. setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void *)&a ...

  4. Tcp之心跳包

    Tcp之心跳包 心跳包 跳包之所以叫心跳包是因为:它像心跳一样每隔固定时间发一次,以此来告诉服务器,这个客户端还活着. 事实上这是为了保持长连接,至于这个包的内容,是没有什么特别规定的,不过一般都是很 ...

  5. 一文读懂Android进程及TCP动态心跳保活

    一直以来,APP进程保活都是 各软件提供商 和 个人开发者 头疼的问题.毕竟一切的商业模式都建立在用户对APP的使用上,因此保证APP进程的唤醒,提升用户的使用时间,便是软件提供商和个人开发者的永恒追 ...

  6. [置顶] android 心跳包的分析

    android 心跳的分析 最近在做一个项目中用到了心跳包的机制,其实就是传统的长连接.或许有的人知道消息推送的机制,消息推送也是一种长连接 ,是将数据有服务器端推送到客户端这边从而改变传统的“拉”的 ...

  7. 嵌入式开发之网络心跳包---阻塞和非阻塞以及是否有必要心跳包heartbeat

    1.1 TCP和UDP的心跳包是用来维持长连接的 心跳包只是用来检测socket的链接状态 2.1 非阻塞情况下TCP 心跳包是否有必要建立心跳包 需要, a.如果说 严格 检测掉线的话 那么不管是不 ...

  8. 网络通信协议三之TCP/IP模型详解

    TCP/IP模型 注:PDU:Protocol Date Unit:表示对等层之间传递的数据单位 TCP:Transmission Control Protocol:传输控制协议 UDP:User D ...

  9. 使用 ssh -R 建立反向/远程TCP端口转发代理

    转自:https://yq.aliyun.com/articles/8469 ssh是一个非常棒的工具, 不但能建立动态转发, 例如chrome的Switchy插件用到的就是这个技术.http://b ...

随机推荐

  1. jQuery中的事件和动画 以及视频展示效果实例

    经过这几天学习jQuery中的事件和动画,对jQuery更深的认识,接下来先把视频展示效果的代码贴出来,最后把我在学习jQuery事件和动画之后总结的思维导图 <!doctype html> ...

  2. 【C】一个读取文件记录器

    分享一下!!! #include<stdio.h> #include<windows.h> #define N 70000 //定义行数!!用空间换取时间 struct stu ...

  3. SQL内外连接的区别

    项目当中,需要将SQL server中的部分数据导入mongo中,由于SQL是关系型数据库的原因,需要联合多表进行查询,因此,了解了下SQL中内外连接的相关概念,以作备注: 1.内联接(典型的联接运算 ...

  4. SEO--HTML meta标签总结

    <!DOCTYPE html> <!-- 使用html5 doctype,不区分大小写--> <html lang="zh-CN"> <h ...

  5. 移动Web开发与适配笔记

    项目要是适配手机端,想透彻的把相关内容弄清楚,现在总结一下. 一.移动端开发有如下特点: 1.跑在手机端的web 页面就是h5页面 2.具有跨平台性(web 安卓 iOS都适应) 3.基于webvie ...

  6. Java学习笔记--继承和多态(下)

    1.通过继承来开发超类(superclass) 2.使用super 关键词唤起超类的构造方法 3.在超类中覆盖方法 4.区分override和overload 5.在Object类中探索toStrin ...

  7. phoneGap异步加载JS失败

    现在正在做一个phoneGap项目,安卓平台,有个异步加载JS总是失败,phoneGap也不好调试,一个问题纠结了一下午 最后找了半天,找到了原因,因此写本文记录一下,也顺便帮帮遇到同样问题的人 原因 ...

  8. c#实体转化

    经常会遇到把一个实体转化成另一个实体这样的情况,实体的属性一个一个手写去转化不反对,但不是啥好的方法:可以使用反射写一个通用的实体转化类,针对任何实体转化,不用再去自己手写. public stati ...

  9. css 伪元素选择器

    /*设置第一个首字母的样式*/ p:first-letter{ color: red; font-size: 30px; } /* 在....之前 添加内容 这个属性使用不是很频繁 了解 使用此伪元素 ...

  10. (生产)vuex - 状态管理

    参考:https://vuex.vuejs.org/zh-cn/ 安装 直接下载 / CDN 引用 https://unpkg.com/vuex在 Vue 之后引入 vuex 会进行自动安装:< ...