文章目录
- 概要&序論
- 一、TCP 异常情况分析
- 1.1 常见 TCP 异常场景
- 1.2 网线拔出时的异常处置与连接重建
- 1.3 连接的保活机制(Keepalive)
- 二、从源码看传输层协议
概要&序論
Hello大家好,我是此方。本文是TCP原理的最后一篇,传输层协议终于要收尾了。本文介绍TCP异常,然后带领大家研究UDP与TCP在源码中的结构。好,我们开始吧。
一、TCP 异常情况分析
在实际网络环境中,通信节点可能会遭遇各种突发异常(如进程崩溃、机器宕机、网线拔出等)。TCP 协议作为一种可靠的传输层协议,设计了完备的异常处理机制与强健的容错能力。
1.1 常见 TCP 异常场景
我这图画得太复杂了,我们边讲边理解
根据异常发生的层级与严重程度,典型的 TCP 异常情况可分为以下几类:
- 进程终止:进程终止时,操作系统会自动释放该进程打开的文件描述符,TCP 协议栈依然可以正常发送 FIN 报文进行四次挥手,这与正常关闭连接没有本质区别。进程退出后,其打开的文件在操作系统中将不再存在。
- 机器重启:机器重启的过程与进程终止的情况相同,关机前操作系统会关闭所有进程并释放相关连接资源。
- 机器掉电或网线断开:接收端在未发生读写时会认为连接依然存在。一旦接收端进行写入操作,就会发现连接已经不存在,进而触发 Reset(RST)报文重置连接。即便没有写入操作,TCP 内部也内置了保活定时器,会定期询问对方是否在线,若对方长期无响应也会自动释放连接。
- 应用层检测机制:除了传输层自身的保活机制外,应用层协议也会设计类似的检测机制(例如 HTTP 长连接中的心跳检测)。像 QQ 等应用在断线后,也会在应用层尝试重新连接。
1.2 网线拔出时的异常处置与连接重建
当客户端突然拔掉网线时,客户端并没有来得及与服务器进行挥手告别,服务端并不知道客户端的网线已经被拔掉。此时的通信与处理逻辑如下:
- 服务器连续发送多条报文后均未收到应答,检测到网络不可达。
- 服务器向客户端发送数据,但长期收不到 ACK,TCP 重传超时后,最终判断连接已经失效。
- 如果服务器删除该连接后,客户端重新插上网线并尝试向服务器发送数据,服务器发现该连接已不存在,就会向客户端发送 RST 报文。客户端收到 RST 后,才知道原来的 TCP 连接已经失效。
- 如果服务器不向客户端发送数据,服务器就没有机会通过发送数据失败来发现客户端已经掉线。
- TCP 本身不会因为对方突然断网就立刻知道连接断开了,必须通过后续的通信活动(或保活机制)才能识别。
不管怎样,这种异常连接最终都会被正确释放,TCP 对异常连接展现出了极强的容错能力。
1.3 连接的保活机制(Keepalive)
为了应对无数据传输场景下的静默断网问题,TCP 提供了 Keepalive 保活机制:
- TCP 内置保活机制的时间间隔通常较大(通常是大约几十分钟级别)。
- 在实际开发中,更及时有效的保活机制往往是由应用层自行实现的(如应用层心跳包)。
- 保活报文主要用于探测连接连通性,通常不包含有效数据载荷。
接下来我们从源码的层面来进一步了解一下传输层协议,也是我们TCP原理部分的收尾,以下是我绘制的一张图,还是比较详细的,一般能看懂。