软件测试中的网络基础-TCP协议

第一部分:TCP 三次握手 (建立连接)

核心目的: 为了保证客户端和服务器双方都具备发送和接收数据的能力。

想象一下打电话的过程:

  1. 你(客户端)给朋友(服务器)打电话。

  2. 朋友听到铃声,接起电话说“喂,你好?”。

  3. 你听到朋友的“喂”,回一句“喂,是我啊!”。

  4. 这时,你们双方都确认了对方能听到自己,也能让自己听到,通话正式建立。

在 TCP 协议中,这个过程被精确地抽象为三次握手。

流程详解:

  1. 第一次握手 (SYN)

    • 客户端 -> 服务器:发送一个 TCP 数据包。

    • 这个包的关键标志位:SYN=1 (Synchronize Sequence Numbers,同步序列号)。

    • 同时,客户端会随机生成一个自己的初始序列号 seq = x

    • 客户端状态:进入 SYN_SENT 状态。

    • 测试视角:如果客户端卡在这个状态,可能是网络防火墙阻断了、服务器端口没开放、或者服务器挂了。

  2. 第二次握手 (SYN + ACK)

    • 服务器 -> 客户端:收到 SYN 包后,必须进行回应。

    • 回应的包包含两个关键标志位:SYN=1 和 ACK=1 (Acknowledgment,确认)。

    • 服务器也会随机生成一个自己的初始序列号 seq = y

    • 同时,确认号 ack = x + 1 (表示“我收到了你的序列号 x,我期望你下次从 x+1 开始发”)。

    • 服务器状态:进入 SYN_RCVD 状态。

    • 测试视角:服务器如果收到大量 SYN_RCVD 状态的连接,可能是遭受了 SYN Flood 洪水攻击(一种拒绝服务攻击)。

  3. 第三次握手 (ACK)

    • 客户端 -> 服务器:收到服务器的 SYN-ACK 包后,再次发送一个确认包。

    • 这个包的标志位:ACK=1

    • 自己的序列号 seq = x + 1 (因为第一次握手消耗了一个序列号)。

    • 确认号 ack = y + 1 (表示“我收到了你的序列号 y,我期望你下次从 y+1 开始发”)。

    • 双方状态:完成这次握手后,客户端和服务器都进入 ESTABLISHED 状态,连接建立成功,可以开始传输数据了。

图解三次握手:

客户端(Client)                          服务器(Server)
    |                                        |
    |-------- SYN (seq=x) ----------->|      (CLOSED -> LISTEN)
    |                                 |      (状态: SYN_RCVD)
    |<---- SYN+ACK (seq=y, ack=x+1) --| 
    |                                 |      (状态: ESTABLISHED)
    |------ ACK (seq=x+1, ack=y+1) -->| 
  (状态: ESTABLISHED)                  |

第二部分:TCP 四次挥手 (终止连接)

核心目的: 为了保证双方的数据都已经传输完毕,才能安全地断开连接。

同样用打电话举例:

  1. 你说:“我说完了,要挂电话了。”

  2. 朋友说:“好的,我知道你说完了。” (但朋友可能还有话没说完)

  3. 朋友把最后几句话说完,然后说:“我也说完了,可以挂了。”

  4. 你说:“好的,拜拜。” 然后挂断。

TCP 是全双工的,即数据可以双向独立传输。因此断开连接需要两个方向分别断开。

流程详解:

  1. 第一次挥手 (FIN)

    • 主动关闭方 (假设是客户端) -> 被动关闭方 (服务器):发送一个 TCP 数据包。

    • 标志位:FIN=1 (Finish,结束),表示我这边的数据发完了,要关闭我到你方向的连接。

    • 序列号 seq = u (一个随机值)。

    • 客户端状态:进入 FIN_WAIT_1 状态。

  2. 第二次挥手 (ACK)

    • 服务器 -> 客户端:收到 FIN 包后,立即发送一个确认包。

    • 标志位:ACK=1

    • 确认号 ack = u + 1

    • 服务器状态:进入 CLOSE_WAIT 状态。此时,从客户端到服务器的连接断了,客户端不能再发数据,但服务器可能还有数据要发给客户端。

    • 客户端状态:收到这个 ACK 后,状态变为 FIN_WAIT_2

  3. 第三次挥手 (FIN)

    • 服务器 -> 客户端:当服务器也把剩下的数据发送完毕后,它会发送一个 FIN 包。

    • 标志位:FIN=1 和 ACK=1

    • 序列号 seq = w

    • 确认号 ack 依然为 u + 1 (因为中间没有数据交互,确认号不变)。

    • 服务器状态:进入 LAST_ACK 状态,等待最后一个确认。

  4. 第四次挥手 (ACK)

    • 客户端 -> 服务器:收到服务器的 FIN 包后,发送一个确认包。

    • 标志位:ACK=1

    • 序列号 seq = u + 1

    • 确认号 ack = w + 1

    • 客户端状态:发送完 ACK 后,进入 TIME_WAIT 状态。等待 2MSL (Maximum Segment Lifetime,最大报文生存时间,通常为 2分钟) 后,状态变为 CLOSED,彻底关闭。

    • 服务器状态:收到这个 ACK 后,状态立即变为 CLOSED

为什么客户端需要 TIME_WAIT 等待?

  • 可靠性:确保服务器收到了最后的 ACK。如果这个 ACK 丢失,服务器在超时后会重发 FIN,客户端在 TIME_WAIT 状态下还能再次回应 ACK。

  • 防旧连接数据混淆:让本次连接的所有报文都在网络中消散,避免被之后新建的、相同四元组(源IP、源端口、目标IP、目标端口)的连接错误接收。

图解四次挥手:

客户端(主动关闭)                  服务器(被动关闭)
    | (状态: ESTABLISHED)          | (状态: ESTABLISHED)
    |--------- FIN (seq=u) ------->| 
    |                             | (状态: CLOSE_WAIT)
    |<------- ACK (ack=u+1) ------| 
    | (状态: FIN_WAIT_1 -> FIN_WAIT_2) |
    |                             | ... 发送剩余数据 ...
    |<------ FIN+ACK (seq=w, ack=u+1) --| 
    |                             | (状态: LAST_ACK)
    |-------- ACK (ack=w+1) ----->| 
    | (状态: TIME_WAIT)            | (状态: CLOSED)
    |(等待 2MSL 后 -> CLOSED)      |

对软件测试工程师的意义

  1. 性能测试与监控

    • 在压力测试中,你可以使用 netstatss 等命令观察服务器上的连接状态。如果发现大量 TIME_WAIT 或 CLOSE_WAIT 状态的连接,可能就是性能瓶颈或 bug 的信号。

    • TIME_WAIT 过多:通常是因为主动关闭连接的次数太多(例如,由服务器端主动关闭),可能会耗尽端口资源。这在压力测试中很常见。

    • CLOSE_WAIT 过多:这是个大坑! 表示你的应用程序(服务器程序)没有及时调用 close() 方法响应对方的 FIN 请求,很可能代码里有资源泄露(如 socket 未关闭)。

  2. 故障分析与定位

    • 测试时遇到“连接超时”、“连接被重置 (RST)”等问题,你可以用 Wireshark、tcpdump 等抓包工具直接捕获 TCP 握手和挥手过程。

    • 看看是第一次握手没响应(网络问题?端口关闭?),还是第三次握手没过去(防火墙规则?),或者是挥手过程不完整(程序bug?)。抓包是定位这类问题的终极利器

  3. 设计测试用例

    • 你可以模拟异常情况来测试软件的健壮性。例如:

      • 模拟只发送 SYN 不回复 ACK(半连接攻击)。

      • 模拟在握手过程中发送 RST 复位包。

      • 模拟异常断开(直接拔网线、杀进程),看程序能否正常处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Oooon_the_way

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值