网易首页 > 网易号 > 正文 申请入驻

不为人知的网络编程:拔掉网线再插上,TCP连接还在吗?一文即懂

0
分享至

本文由作者小林coding分享,来自公号“小林coding”,有修订和改动。

1、引言

说到TCP协议,对于从事即时通讯/IM这方面应用的开发者们来说,再熟悉不过了。随着对TCP理解的越来越深入,很多曾经碰到过但没时间深入探究的TCP技术概念或疑问,现在是时候回头来恶补一下了。

本篇文章,我们就从系统层面深入地探讨一个有趣的TCP技术问题:拔掉网线后,再插上,原本的这条TCP连接还在吗?或者说它还“好”吗?

可能有的人会说:网线都被拔掉了,那说明物理层(也叫实体层)被断开了(关于网络协议分层模型请见《快速理解网络通信协议(上篇)》),那在物理层之上的传输层理应也会断开,所以原本的 TCP 连接就不会存在的了。就好像我们拨打有线电话的时候,如果某一方的电话线被拔了,那么本次通话就彻底断了。

答案真的是这样吗?可能并非你理解的这样哦,一起跟随笔者来深入探讨一下。

2、系列文章

本文是系列文章中的第14篇,本系列文章的大纲如下:

  • 《不为人知的网络编程(一):浅析TCP协议中的疑难杂症(上篇)》
  • 《不为人知的网络编程(二):浅析TCP协议中的疑难杂症(下篇)》
  • 《不为人知的网络编程(三):关闭TCP连接时为什么会TIME_WAIT、CLOSE_WAIT》
  • 《不为人知的网络编程(四):深入研究分析TCP的异常关闭》
  • 《不为人知的网络编程(五):UDP的连接性和负载均衡》
  • 《不为人知的网络编程(六):深入地理解UDP协议并用好它》
  • 《不为人知的网络编程(七):如何让不可靠的UDP变的可靠?》
  • 《不为人知的网络编程(八):从数据传输层深度解密HTTP》
  • 《不为人知的网络编程(九):理论联系实际,全方位深入理解DNS》
  • 《不为人知的网络编程(十):深入操作系统,从内核理解网络包的接收过程(Linux篇)》
  • 《不为人知的网络编程(十一):从底层入手,深度分析TCP连接耗时的秘密》
  • 《不为人知的网络编程(十二):彻底搞懂TCP协议层的KeepAlive保活机制》
  • 《不为人知的网络编程(十三):深入操作系统,彻底搞懂127.0.0.1本机网络通信》
  • 《不为人知的网络编程(十四):拔掉网线再插上,TCP连接还在吗?一文即懂!》(* 本文)
3、比较笼统的答案

3.1 答案

引言里我们说到:有人认为,网线都被拔掉了,那说明物理层被断开,那么物理层之上的传输层肯定也会断开,所以原来的 TCP 连接自然也就不存在了。(PS:计算机网络分层详解请见《史上最通俗计算机网络分层详解》)

上面这个逻辑是有问题的。

问题在于:错误的认为拔掉网线这个动作会影响传输层,事实上并不会影响!

实际上:TCP 连接在 Linux 内核中是一个名为 struct socket 的结构体,该结构体的内容包含 TCP 连接的状态等信息。

所以:当拔掉网线的时候,操作系统并不会变更该结构体的任何内容,所以 TCP 连接的状态也不会发生改变。

3.2 实验验证一下

我做了个小实验:我用 ssh 终端连接了我的云服务器,然后我通过断开 wifi 的方式来模拟拔掉网线的场景,此时查看 TCP 连接的状态没有发生变化,还是处于 ESTABLISHED 状态(如下图所示)。

通过上面实验结果可以验证我的结论:拔掉网线这个动作并不会影响 TCP 连接的状态。

不过,这个答案还是有点笼统。实际上,我们应该在更具体的场景中来看待这个问题,答案才更准确一些。

这个具体场景就是:

  • 1)当拔掉网线后,有数据传输时;
  • 2)当拔掉网线后,没有数据传输时。

针对上面这两种具体的场景,我来更具体地来分析一下。我们继续往下阅读。

4、具体场景1:拔掉网线后,有数据传输时

4.1 数据传输过程中,恰好又把网线插回去了

如果是客户端被拔掉网线后,服务端向客户端发送的数据报文会得不到任何的响应,在等待一定时长后,服务端就会触发TCP协议的超时重传机制(详见:《TCP/IP详解 - 第21章·TCP的超时与重传》),然而此时重传并不能得到响应的数据报文。

如果在服务端重传报文的过程中,客户端恰好把网线插回去了,由于拔掉网线并不会改变客户端的 TCP 连接状态,并且还是处于 ESTABLISHED 状态,所以这时客户端是可以正常接收服务端发来的数据报文的,然后客户端就会回 ACK 响应报文。

此时:客户端和服务端的 TCP 连接将依然存在且工作状态不会受到影响,给应用层的感觉就像什么事情都没有发生。。。

4.2 数据传输过程中,网线一直没有插回去

上面这种情况下,如果在服务端TCP协议重传报文的过程中,客户端一直没有将网线插回去,那么服务端超时重传报文的次数达到一定阈值后,内核就会判定出该 TCP 有问题。然后就会通过 Socket 接口告诉应用程序该 TCP 连接出问题了,于是服务端的 TCP 连接就会断开。

接下来,如果客户端再插回网线,如果客户端向服务端发送了数据,由于服务端已经没有与客户端匹配的 TCP 连接信息了,因此服务端内核就会回复 RST 报文,客户端收到后就会释放该 TCP 连接。

此时:客户端和服务端的 TCP 连接已经明确被断开,原本的这个连接也就不存在了。

4.3 刨根问底:TCP数据报文到底重传几次?

本着知其然更应知其所以然的精神,我们来刨根问底一下:TCP 的数据报文到底有重传几次呢?

在 Linux 系统中,提供了一个叫 tcp_retries2 配置项,默认值是 15(如下图所示)。

如上图所示:这个内核参数是控制 TCP 连接建立的情况下,超时重传的最大次数。

不过 tcp_retries2 设置了 15 次,并不代表 TCP 超时重传了 15 次才会通知应用程序终止该 TCP 连接,内核还会基于“最大超时时间”来判定。

每一轮的超时时间都是倍数增长的,比如第一次触发超时重传是在 2s 后,第二次则是在 4s 后,第三次则是 8s 后,以此类推。

内核会根据 tcp_retries2 设置的值,计算出一个最大超时时间。

在重传报文且一直没有收到对方响应的情况时,先达到“最大重传次数”或者“最大超时时间”这两个的其中一个条件后,就会停止重传,然后就会断开 TCP 连接。

PS:有关TCP超时重传机制的详细情况,可以阅读《浅析TCP协议中的疑难杂症(下篇)》。

5、具体场景2:拔掉网线后,有数据传输时

5.1 场景分析

针对拔掉网线后,没有数据传输的场景,还得具体看看是否开启了 TCP KeepAlive 机制 (详见《彻底搞懂TCP协议层的KeepAlive保活机制》)。

1)如果没有开启 TCP KeepAlive 机制:

在客户端拔掉网线后,并且双方都没有进行数据传输,那么客户端和服务端的 TCP 连接将会一直保持存在。

2)如果开启了 TCP KeepAlive 机制:

在客户端拔掉网线后,即使双方都没有进行数据传输,在持续一段时间后,TCP 就会发送KeepAlive探测报文。

根据KeepAlive探测报文响应情况,会有以下两种可能:

  • 1)如果对端正常工作:当探测报文被对端收到并正常响应, TCP 保活时间将被重置,等待下一个 TCP 保活时间的到来;
  • 2)如果对端主机崩溃或对端由于其他原因导致报文不可达:当探测报文发送给对端后,石沉大海、没有响应,连续几次,达到保活探测次数后,TCP 会报告该连接已经死亡。

所以:TCP 保活机制可以在双方没有数据交互的情况,通过TCP KeepAlive 机制的探测报文,来确定对方的 TCP 连接是否存活。

5.2 刨根问底:TCP KeepAlive 机制具体是什么样的?

TCP KeepAlive 机制的原理是这样的:

定义一个时间段,在这个时间段内,如果没有任何连接相关的活动,TCP 保活机制会开始作用,每隔一个时间间隔,发送一个探测报文。该探测报文包含的数据非常少,如果连续几个探测报文都没有得到响应,则认为当前的 TCP 连接已经死亡,系统内核将错误信息通知给上层应用程序。

在 Linux 内核可以有对应的参数可以设置保活时间、保活探测的次数、保活探测的时间间隔。

以下是 Linux 中的默认值:

net.ipv4.tcp_keepalive_time=7200
net.ipv4.tcp_keepalive_intvl=75
net.ipv4.tcp_keepalive_probes=9

解释一下:

  • 1)tcp_keepalive_time=7200:表示保活时间是 7200 秒(2小时),也就 2 小时内如果没有任何连接相关的活动,则会启动保活机制;
  • 2)tcp_keepalive_intvl=75:表示每次检测间隔 75 秒;
  • 3)tcp_keepalive_probes=9:表示检测 9 次无响应,认为对方是不可达的,从而中断本次的连接。

也就是说在 Linux 系统中,最少需要经过 2 小时 11 分 15 秒才可以发现一个“死亡”连接。

计算公式是:

注意:应用程序若想使用 TCP 保活机制需要通过 socket 接口设置 SO_KEEPALIVE 选项才能够生效,如果没有设置,那么就无法使用 TCP 保活机制。

PS:关于TCP协议的KeepAlive 机制详见《彻底搞懂TCP协议层的KeepAlive保活机制》、《一文读懂即时通讯应用中的网络心跳包机制:作用、原理、实现思路等》。

5.3 刨根问底:TCP KeepAlive 机制的探测时间也太长了吧?

没错,确实有点长。

TCP KeepAlive 机制是 TCP 层(内核态) 实现的,它是给所有基于 TCP 传输协议的程序一个兜底的方案。

实际上:我们通常在应用层自己实现一套探测机制,可以在较短的时间内,探测到对方是否存活。

比如:一般Web 服务器都会提供 keepalive_timeout 参数,用来指定 HTTP 长连接的超时时间。如果设置了 HTTP 长连接的超时时间是 60 秒,Web 服务软件就会启动一个定时器,如果客户端在完后一个 HTTP 请求后,在 60 秒内都没有再发起新的请求,定时器的时间一到,就会触发回调函数来释放该连接。

再比如:IM、消息推送系统里的心跳机制,通过应用层的心跳机制(由客户端发出,服务端回复响应包),来灵活控制和探测长连接的健康度。

《为何基于TCP协议的移动端IM仍然需要心跳保活机制?》这篇文章解释了IM这类应用中应用层心跳保活的必要性,有兴趣可以读一读。

如果对应用层心跳的具体应用没什么概念,可以看看微信的这两篇文章:

  1. 《微信团队原创分享:Android版微信后台保活实战分享(网络保活篇)》
  2. 《移动端IM实践:实现Android版微信的智能心跳机制》

下面有几个针对im这类应用的心跳实现代码,可以具体感受学习一下:

  1. 《正确理解IM长连接的心跳及重连机制,并动手实现(有完整IM源码)》
  2. 《一种Android端IM智能心跳算法的设计与实现探讨(含样例代码)》
  3. 《自已开发IM有那么难吗?手把手教你自撸一个Andriod版简易IM (有源码)》
  4. 《手把手教你用Netty实现网络通信程序的心跳机制、断线重连机制》
6、本文小结

下面简单总结一下文中的内容,本文开头的问题并不是简单一句话能够准确说清楚的,需要分情况对待。

也就是:客户端拔掉网线后,并不会直接影响 TCP 的连接状态。所以拔掉网线后,TCP 连接是否还会存在,关键要看拔掉网线之后,有没有进行数据传输。

1)有数据传输的情况:

在客户端拔掉网线后:如果服务端发送了数据报文,那么在服务端重传次数没有达到最大值之前,客户端恰好插回网线的话,那么双方原本的 TCP 连接还是能存在并正常工作,就好像什么事情都没有发生。

在客户端拔掉网线后:如果服务端发送了数据报文,在客户端插回网线之前,服务端重传次数达到了最大值时,服务端就会断开 TCP 连接。等到客户端插回网线后,向服务端发送了数据,因为服务端已经断开了与客户端相同四元组的 TCP 连接,所以就会回 RST 报文,客户端收到后就会断开 TCP 连接。至此, 双方的 TCP 连接都断开了。

2)没有数据传输的情况:

  • a. 如果双方都没有开启 TCP keepalive 机制,那么在客户端拔掉网线后,如果客户端一直不插回网线,那么客户端和服务端的 TCP 连接状态将会一直保持存在;
  • b. 如果双方都开启了 TCP keepalive 机制,那么在客户端拔掉网线后,如果客户端一直不插回网线,TCP keepalive 机制会探测到对方的 TCP 连接没有存活,于是就会断开 TCP 连接。而如果在 TCP 探测期间,客户端插回了网线,那么双方原本的 TCP 连接还是能正常存在。

除了客户端拔掉网线的场景,还有客户端“宕机和杀死进程”的两种场景。

第一个场景:客户端宕机这件事跟拔掉网线是一样无法被服务端的感知的,所以如果在没有数据传输,并且没有开启 TCP keepalive 机制时,,服务端的 TCP 连接将会一直处于 ESTABLISHED 连接状态,直到服务端重启进程。

所以:我们可以得知一个点——在没有使用 TCP 保活机制,且双方不传输数据的情况下,一方的 TCP 连接处在 ESTABLISHED 状态时,并不代表另一方的 TCP 连接还一定是正常的。

第二个场景:杀死客户端的进程后,客户端的内核就会向服务端发送 FIN 报文,与客户端进行四次挥手(见《跟着动画来学TCP三次握手和四次挥手》)。

所以:即使没有开启 TCP KeepAlive,且双方也没有数据交互的情况下,如果其中一方的进程发生了崩溃,这个过程操作系统是可以感知的到的,于是就会发送 FIN 报文给对方,然后与对方进行 TCP 四次挥手。

7、参考资料

[1] TCP/IP详解 - 第21章·TCP的超时与重传

[2] 通俗易懂-深入理解TCP协议(上):理论基础

[3] 网络编程懒人入门(三):快速理解TCP协议一篇就够

[4] 脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

[5] 脑残式网络编程入门(七):面试必备,史上最通俗计算机网络分层详解

[6] 技术大牛陈硕的分享:由浅入深,网络编程学习经验干货总结

[7] 网络编程入门从未如此简单(二):假如你来设计TCP协议,会怎么做?

[8] 不为人知的网络编程(十):深入操作系统,从内核理解网络包的接收过程(Linux篇)

[9] 为何基于TCP协议的移动端IM仍然需要心跳保活机制?

[10] 一文读懂即时通讯应用中的网络心跳包机制:作用、原理、实现思路等

[11] Web端即时通讯实践干货:如何让你的WebSocket断网重连更快速?

学习交流:

  • - 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM》
  • - 开源IM框架源码:https://github.com/JackJiang2011/MobileIMSDK

(本文同步发布于:http://www.52im.net/thread-3846-1-1.html)

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
冯提莫被封号,平台这次是玩真的

冯提莫被封号,平台这次是玩真的

电商报APP
2024-06-12 14:15:43
【环时军事观察】俄海军编队访古巴为什么让西方紧张?

【环时军事观察】俄海军编队访古巴为什么让西方紧张?

环球网资讯
2024-06-12 07:08:22
地主刘继祖给朱元璋一块地葬父,他当上皇帝后,是如何报答他的?

地主刘继祖给朱元璋一块地葬父,他当上皇帝后,是如何报答他的?

知否否
2024-05-25 13:34:39
当90后杨紫穿旗袍80后撞上柳岩,终于知道了纯情与风情差距有多大

当90后杨紫穿旗袍80后撞上柳岩,终于知道了纯情与风情差距有多大

酒盅故事汇
2024-06-11 18:27:56
《沃尔夫条款》引争议:美国拿不到中国采样回来的月壤为何不急?

《沃尔夫条款》引争议:美国拿不到中国采样回来的月壤为何不急?

嘿哥哥科技
2024-06-12 19:35:14
小S参加大女儿毕业晚会,母女同框比美,18岁许曦文身材完胜妈妈

小S参加大女儿毕业晚会,母女同框比美,18岁许曦文身材完胜妈妈

娱絮
2024-06-12 10:17:08
法国人后悔,开始反极右游行!总理阿塔尔和小马CP掰了,网友心疼塔塔……

法国人后悔,开始反极右游行!总理阿塔尔和小马CP掰了,网友心疼塔塔……

新欧洲
2024-06-11 20:19:03
泰国3-1却面如死灰!美女足协主席很绝望,哨响6人瘫倒,捂脸痛哭

泰国3-1却面如死灰!美女足协主席很绝望,哨响6人瘫倒,捂脸痛哭

嘴炮体坛
2024-06-11 22:48:43
CBA最新消息!新疆男篮更换教练,潘江成为主帅,陈盈骏离开广州

CBA最新消息!新疆男篮更换教练,潘江成为主帅,陈盈骏离开广州

体坛瞎白话
2024-06-12 10:29:16
顶替姆巴佩!巴黎挖皇马头牌!豪掷1.5亿+天价高薪,佛爷没办法

顶替姆巴佩!巴黎挖皇马头牌!豪掷1.5亿+天价高薪,佛爷没办法

阿泰希特
2024-06-12 14:55:05
1981年,他被连队关禁闭借故爬上大树解闷,一亮光改变了他的人生

1981年,他被连队关禁闭借故爬上大树解闷,一亮光改变了他的人生

百年历史老号
2024-06-12 07:38:26
美军公布“艾森豪威尔”号新照片,甲板未塌陷,胡塞武装牛皮吹破

美军公布“艾森豪威尔”号新照片,甲板未塌陷,胡塞武装牛皮吹破

三分亮剑
2024-06-11 14:21:43
港媒也太“勇”了吧!李嘉欣的照片不修一下就发出来,状态太真实

港媒也太“勇”了吧!李嘉欣的照片不修一下就发出来,状态太真实

影苏爱时尚
2024-06-11 18:28:04
3天倒计时!菲撤离了一艘破船:即将面临物资断绝的困境

3天倒计时!菲撤离了一艘破船:即将面临物资断绝的困境

青年的背包
2024-06-12 13:13:22
拱北海关原关长周斌,在党的十八大、十九大乃至二十大后仍然不收敛、不收手、不知止

拱北海关原关长周斌,在党的十八大、十九大乃至二十大后仍然不收敛、不收手、不知止

新京报政事儿
2024-06-12 16:15:12
参加《浪姐》后,朱丹瘦了好多 腰细了 更漂亮了

参加《浪姐》后,朱丹瘦了好多 腰细了 更漂亮了

娱记掌门
2024-06-12 15:09:56
炸了!美国大使亲口承认:中国要全面超越美国啦!

炸了!美国大使亲口承认:中国要全面超越美国啦!

仰望沧海
2024-06-12 13:32:06
大量华人遣返!“靖国神厕”铁头“尿尿效应”凸显!日本:不遣返留着你们都来撒?

大量华人遣返!“靖国神厕”铁头“尿尿效应”凸显!日本:不遣返留着你们都来撒?

亚哥谈古论今
2024-06-12 18:16:18
朱德甫被查!任职地已有多名干部被处理

朱德甫被查!任职地已有多名干部被处理

上观新闻
2024-06-12 15:25:24
厦门有大动作,台军一把手脸色都变了,放豪言:我要找大陆说清楚

厦门有大动作,台军一把手脸色都变了,放豪言:我要找大陆说清楚

千里持剑
2024-06-12 15:00:30
2024-06-12 21:58:44
即时通讯技术分享
即时通讯技术分享
即时通讯相关技术的研究与分享
382文章数 3612关注度
往期回顾 全部

科技要闻

谁是苹果AI的“中国合伙人”?

头条要闻

卸任6年的"甘肃虎"被查 曾是正部级"老虎"唐仁健下属

头条要闻

卸任6年的"甘肃虎"被查 曾是正部级"老虎"唐仁健下属

体育要闻

国足,别辜负这场奇迹!

娱乐要闻

黄一鸣再次录视频表态孩子是王思聪的

财经要闻

徽商银行的影子 借基金向地方城投放贷?

汽车要闻

理想汽车周销量突破1万辆 单周销量首超宝马奥迪

态度原创

手机
教育
亲子
健康
军事航空

手机要闻

3473元起!小米14 CIVI发布:Civi 4 Pro海外更名版

教育要闻

衡水教育抢滩青岛,复读市场硝烟再起

亲子要闻

孩子爱撒谎,根本原因在哪里?

晚餐不吃or吃七分饱,哪种更减肥?

军事要闻

美国解禁乌克兰"亚速营"使用美制武器 俄方回应

无障碍浏览 进入关怀版