tcp 连接 三次握手 四次挥手

 

来自:https://cloud.tencent.com/developer/article/1893375

前言

看到这个标题你可能会说,TCP 连接的建立与断开,这个我熟,不就是三次握手与四次挥手嘛。且慢,脑海中可以先尝试回答这几个问题:

  • 四次挥手是谁发起的?
  • 如果断电/断网了连接会断开吗?
  • 什么情况下没有四次挥手连接也会断开?

这不是面试,而是遇到了实际问题,至于是什么问题,容我先卖个关子,本文也不会解答,后面会有一篇专门的文章来说遇到的问题是啥,所以在讲实际问题之前,先弄懂理论。

正常断开

我们由浅入深,先了解正常情况下 TCP 连接是如何断开的,下图为 TCP 三次握手与四次挥手的经典图(来自《TCP/IP详解卷1》)

img1.png
img1.png

在我们的电脑上,可以使用 python 的 SimpleHTTPServer 来快速起一个 http 服务(http 也是基于 TCP 协议),比如这样:

python -m SimpleHTTPServer 20880

再通过 nctelnet 这两个命令来创建 TCP 连接,比如我测试使用 nc 来创建连接

nc -v ip port

Connection to ip port [tcp/*] succeeded! 表示连接成功

img2.png
img2.png

我们如何观察这个连接呢?可以通过 netstatlsof 来查看这条"连接",这里我使用 lsof(mac 与 Linux 系统的 netstat 命令不太一样,使用起来有点别扭 )

lsof -i:20880

img3.png
img3.png

无论是客户端还是服务端都会占用一个端口,不过服务端端口是固定的,客户端端口是随机的。

如果我们想看 TCP 连接和断开时握手挥手的 TCP 报文怎么查看呢?可以使用 tcpdump 命令

三次握手

tcpdump -A -vv -i any -S host 10.179.245.95

为了方便查看,和上面的经典图放在了一起

img4.png
img4.png

 

总结

除了正常情况之外,本文从 TCP 连接断开的角度结合实验给出了一些结论:

  • TCP 连接断开的挥手,在进程崩溃时,会由操作系统内核代劳
  • 当 TCP 连接建立后,如果某一方断电或断网,如果此时刚好正在发送数据,TCP 数据包发送失败后会重试,重试达到上限时也会断开连接
  • 当 TCP 连接建立后,如果某一方断电或断网,且这条连接没有数据传输时
    • 如果开启了 KeepAlive 则会在一定心跳检测后断开连接,这个默认检测时间大概2个多小时,比较久
    • 如果未开启 KeepAlive 则连接永远存在
  • 如果一方发送 RST 包给另一方,也是会强制对方断开连接的

 

参考:

https://cloud.tencent.com/developer/article/1893375

posted @ 2024-06-18 11:54  redrobot  阅读(2)  评论(0编辑  收藏  举报