TCP心跳的意义
摘自: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心跳的意义的更多相关文章
- tcp/心跳包
1,http://blog.csdn.net/yuzhiyuxia/article/details/7857508 心跳包就是在客户端和服务器间定时通知对方自己状态的一个自己定义的命令字,按照一定的时 ...
- TCP心跳包
所谓的心跳包就是客户端定时放送简单的信息给服务器端,告诉它我还在而已.代码就是每 隔几分钟发送一个固定信息给服务器端,服务器端回复一个固定信息.如果服务器端几分钟后没有收到客户端信息则视客户端断开.比 ...
- TCP心跳 | TCP keepAlive(转)
应用层对于每个socket采用如下函数来开启 keepalive机制,其参数将采用系统上述配置. setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void *)&a ...
- Tcp之心跳包
Tcp之心跳包 心跳包 跳包之所以叫心跳包是因为:它像心跳一样每隔固定时间发一次,以此来告诉服务器,这个客户端还活着. 事实上这是为了保持长连接,至于这个包的内容,是没有什么特别规定的,不过一般都是很 ...
- 一文读懂Android进程及TCP动态心跳保活
一直以来,APP进程保活都是 各软件提供商 和 个人开发者 头疼的问题.毕竟一切的商业模式都建立在用户对APP的使用上,因此保证APP进程的唤醒,提升用户的使用时间,便是软件提供商和个人开发者的永恒追 ...
- [置顶] android 心跳包的分析
android 心跳的分析 最近在做一个项目中用到了心跳包的机制,其实就是传统的长连接.或许有的人知道消息推送的机制,消息推送也是一种长连接 ,是将数据有服务器端推送到客户端这边从而改变传统的“拉”的 ...
- 嵌入式开发之网络心跳包---阻塞和非阻塞以及是否有必要心跳包heartbeat
1.1 TCP和UDP的心跳包是用来维持长连接的 心跳包只是用来检测socket的链接状态 2.1 非阻塞情况下TCP 心跳包是否有必要建立心跳包 需要, a.如果说 严格 检测掉线的话 那么不管是不 ...
- 网络通信协议三之TCP/IP模型详解
TCP/IP模型 注:PDU:Protocol Date Unit:表示对等层之间传递的数据单位 TCP:Transmission Control Protocol:传输控制协议 UDP:User D ...
- 使用 ssh -R 建立反向/远程TCP端口转发代理
转自:https://yq.aliyun.com/articles/8469 ssh是一个非常棒的工具, 不但能建立动态转发, 例如chrome的Switchy插件用到的就是这个技术.http://b ...
随机推荐
- pip安装flask问题解决
环境:python 2.7 pip install virtualenv pip install flask 提示成功但无效 查看http://docs.jinkan.org/docs/flask/i ...
- java 日志框架的选择Log4j->SLF4j->Logback
Log4j->SLF4j->Logback是同一个人开发的 import lombok.extern.slf4j.Slf4j; import org.junit.Test; import ...
- Qt 学习(4)
Qt UI 文件机制 使用 Qt 设计界面程序时,若界面是静态的,可以借助 Qt Designer 进行所见即所得的界面设计.设计好界面后,在界面类中对 ui 对象进行操作非常方便. QtCreato ...
- [Eclipse]自动注释功能
1) 新建一个file时,加上一些注释的方法. window->preference->java->code styple->code template 当你选 ...
- MVC数据库问题(更新,添加字段)
1.更新模型之后,在"程序包管理控制器"中输入Update-database,就能自动完成更新 2.对于Update-database之后报错:Automatic migratio ...
- MacOS python自动补全设置
1. 新建python自动补全脚步 $ cd <workdir> $ touch tab.py $ vim tab.py,输入如下内容后保存 $ chmod +x tab.py #!/us ...
- flexpager权限控制文件crossdomain.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE cross-domain-policy SY ...
- Android数据绑定技术二,企业级开发
PS:上一篇文章写了Databinding的简单使用,写了一个绑定textview的示例,和绑定的一些用法,估计有的人会说,之前的写的好好的,为什么要数据绑定这样的写法呢,没办法,社会在进步,当然是怎 ...
- android api 之Scroller
Scroller是封装了滚动,实现View和ViewGroup的背景画布的滚动. 它有两个构造方法: public Scroller (Context context) 传递一个上下文. public ...
- appium-python-api中文文档
来自https://wenku.baidu.com/view/533603ce581b6bd97e19eaa1.html mark,同时提供给需要使用python写脚本的童鞋们