在网络通信中,TCP (Transmission Control Protocol,传输控制协议)是一个可靠的、面向连接的协议,它保证了数据包的顺序和完整性。为了建立一个稳定的连接,TCP 使用了一个被称为 三次握手(Three-Way Handshake)的过程。在本文,我们将深入剖析 TCP 三次握手的工作原理。
三次握手是啥?
是 TCP 协议用来建立连接的一种机制,这个过程由客户端和服务器之间的三个步骤组成,目的是在通信开始前双方确认对方的接收和发送能力。
三次握手的三个步骤如下:
- SYN(Synchronize) :客户端向服务器发送一个带有 SYN 标志位的 TCP 报文段。该报文段包含一个随机生成的序列号 Seq=x,表示客户端的初始序列号。
- SYN-ACK(Synchronize-Acknowledge) :当服务器收到客户端的 SYN 请求后,它会向客户端发送一个带有 SYN 和 ACK 标志位的 TCP 报文段,表示它同意建立连接。同时,服务器也会发送自己的初始序列号 Seq=y ,并且确认客户端的序列号 Ack=x+1,表示已经收到客户端的 SYN。
- ACK(Acknowledge) :当客户端收到服务器的 SYN-ACK 报文段后,客户端会向服务器发送一个确认报文 ACK 确认收到了服务器的序列号 Ack=y+1 ,并且使用自己原来的序列号 Seq=x+1。
大白话版本:
- 你:"嗨,最近有空吗?我们去吃个饭?"
- 朋友:"好的,我有空,那你准备好了吗?"
- 你:"好的,我也准备好了,我们去吃饭吧。"
在这三次通信完成后,TCP 连接就正式建立,双方可以开始传输数据。
口说无凭,事实说话(看看到底发了个啥)
我们在局域网内找一台 Ubuntu 20.04 并部署一个 nginx 服务。然后通过 http 请求看看连接数据。HTPP/1.1 和 HTTP/2 底层的网络通信用的都是 TCP,所以拿这个测试没啥毛病~
安装 nginx 并启动 tcpdump 抓包工具
- 更新软件包索引
bash
sudo apt install nginx
- 安装 Nginx
bash
sudo apt install nginx
- 配置防火墙
bash
sudo ufw allow 'Nginx HTTP'
sudo ufw allow 'Nginx HTTPS'
- 查看 nginx 的状态
bash
systemctl status nginx
状态如下所示就代表正在运行。
- tcpdump 捕获数据包
bash
sudo tcpdump -i ens33 -S -c 3 port 80
参数说明:
- -i ens33:指定网络接口 ens33(根据自己实际情况来)
- -S:显示数据包的绝对序列号,这样更易懂
- -c 3:只捕获 3 个数据包后停止(3 次握手)
- port 80:HTTP 端口,nginx 默认是 80
访问
我们直接使用同一局域网内其他电脑的浏览器访问即可:
http://192.168.192.137:80
结果分析
tcpdump 抓包结果显示如下:
说明:
1 是客户端 -> 服务端
2 是服务端 -> 客户端
3 是客户端 -> 服务端
你可以仔细看一下结果中的 seq 和 ack,再对应三次握手的概念图,是不是一下就明白了!