背景

最近面试了很多的学生,发现很多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的初学者而言是个大坑,我写这篇文章希望初学者能够在编写TCP程序时避免这个坑,同时也希望面试者能够深入理解TCP的心跳机制,能够取得更好的面试结果。

TCP新手误区–心跳的意义相关推荐

  1. 性能测试报告模板_性能测试新手误区

    >>>推荐阅读<<< 1.性能测试学习笔记-场景设计 2.性能测试的重要意义 3.性能分析流程及方法 4.应用系统性能调优之性能分析 性能测试新手误区 性能测试新手 ...

  2. 做python自动化得时候怎么添加断言_在编写Web自动化测试用例的时候,如何写断言使新手不解,严格意义上来讲,没有断言的自动化脚本不能叫测试用例。就像功能测试一样,当测试人员做了一些操作...

    在编写Web自动化测试用例的时候,如何写断言使新手不解,严格意义上来讲,没有断言的自动化脚本不能叫测试用例.就像功能测试一样,当测试人员做了一些操作之后必然会判断实际结果是否等于预期结果,只不过,这个 ...

  3. 服务器压力测试_性能测试新手误区(四):一切来自录制

    :新书 速递 吴老的java版<selenium webdriver 实战宝典>和python版<selenium Webdriver 3.0 自动化测试框架实战指南>出版了, ...

  4. TCP 三次握手的意义

    概述 在网络的传输层协议中, 存在着两大悍将: TCP 和 UDP . 从前, 我傻傻的以为自己对他们虽谈不上精通, 但还是知道的, 但是, 我错了, 我被自己问住了, 我傻了. 啥也不是. UDP ...

  5. 10个常见的Android 新手误区

    在过去十年的移动开发平台中,作为资深的移动开发人员,我们认为Android平台是一个新手最广为人知的平台.它不仅是一个廉价的工具,而且有着良好的开发社区,以及从所周知的编程语言(Java),使得开发A ...

  6. TCP连接的心跳包机制

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

  7. 转:10个常见的 Android 新手误区

    转自:http://www.oschina.net/question/157182_61140 1.不读Android开发文档 Android开发者网站可以很好的帮助你.很多的文档也可以通过SDK工具 ...

  8. 南柯服务器压力,性能测试新手误区(四):一切来自录制

    4zayyX051Testing软件测试网2YP g6@(^y51Testing软件测试网3Z[9lSZ51Testing软件测试网6Lm4Pp$@F| 51Testing软件测试网lG-b%bKb( ...

  9. SoX 安装(Ubuntu+win10)的新手误区和正确安装方法。

    转载请声明出处! 1.绪论 SoX - Sound eXchange 国外开源音频处理软件,官网地址:http://sox.sourceforge.net/Main/HomePage. Welcome ...

  10. 软件测试新手误区-追求最新版本的测试工具

    新手在学习软件测试时都喜欢找些测试工具来学学,什么QTP啦! LoadRunner啦! Quality Center啦!学习工具的使用和操作方法是好事,即使现在不能用上,将来也有可能有机会用到,作为技 ...

最新文章

  1. wxWidgets:wxEventBlocker类用法
  2. 同程旅行王晓波:同程凤凰缓存系统在基于 Redis 方面的设计与实践(上篇)
  3. 【java】List 根据实体属性值搜索
  4. 03-谷歌浏览器安装Sence
  5. 实用的 Python 之 feedparser
  6. nginx实时生成缩略图到硬盘上
  7. 对称密钥密码体制的主要特点
  8. Unity摄像机上下旋转镜头实现
  9. 统计基础:3.3_假设检验之t检验(Student‘s t test)
  10. crosstab交叉表_用Python统计推断——交叉表篇(上:crosstab与热图)
  11. Switch组件的使用
  12. 20145212罗天晨 后门原理与实践
  13. 能够翻译文档的免费软件-免费翻译整个文档的软件
  14. 需要给变量赋缺省值吗?
  15. Mac Terminal 美化
  16. google play 此应用使用的结算功能版本已不能受支持。
  17. face_recognition人脸识别框架
  18. uniapp 学习笔记二十二 购物车页面结构搭建
  19. 使用nginx部署django
  20. Flutter App上架google play 流程以及遇到的坑(已经解决,App已经发布成功)

热门文章

  1. 阿里开发者们的第15个感悟:做一款优秀大数据引擎,要找准重点解决的业务场景... 1
  2. 美图为什么布局AR增强现实?
  3. input文本框的readonly和disabled属性区别
  4. Nginx的负载均衡 - 加权轮询 (Weighted Round Robin) 上篇
  5. iOS之01-基本语法
  6. 浅议磁盘分区——从MBR到GPT
  7. 在数据库中存储层次型数据
  8. 3.GitLab 用户管理
  9. 10.TCP/IP 详解卷1 --- 动态选路协议
  10. 124. PHP 性能分析