循序渐进搞懂 TCP 三次握手核心

本文通过实例和详细步骤解释了TCP三次握手的过程,帮助初学者理解这一网络通信的基础知识。从通俗的电话交流比喻,到TCP报文段的结构分析,再到实际的服务器端和客户端交互,最后通过Wireshark捕获封包验证握手过程。文中还展示了TCP连接状态机的状态变化,以加深对TCP连接建立的理解。
摘要由CSDN通过智能技术生成

前言

本文旨在通过形象的例子和实操,把无形的、虚拟的网络转为具体的、可视化的。带领网络小白一步步的掌握 TCP 三次握手核心知识点,为后续深入学习 TCP 协议打基础。

通俗版

如下图所示,小明(客户端)给小美(服务端)打电话,在经过互相询问和应答,确认通信畅通后,才开始愉快地聊天。(本例子不一定无懈可击主要是意会即可)

编辑

添加图片注释,不超过 140 字(可选)

细节版

一个 TCP 报文段分为首部和数据两部分,TCP 所有的功能都体现在首部的各个字段中。

编辑切换为居中

添加图片注释,不超过 140 字(可选)

序列号:本报文段所发送数据的第一个字节的序号,在建立连接时会随机生成初始序列号 ISN(Inital Sequence Number)。

确认号:下一次应该收到的数据的序列号,若确认号为 N,则代表到序列号 N-1 为止的数据都已经正确收到。

控制位:

  • ACK:为 1 时确认号才生效,在建立连接后所有传送的报文段 ACK 均为 1。

  • SYN:为 1 时表示这是连接请求(SYN=1,ACK=0)或者连接接受(SYN=1,ACK=1)报文。

编辑

添加图片注释,不超过 140 字(可选)

由于上述报文都未携带数据,即 len=0,所以响应的 ack 等于请求的 seq+1。

实战版

为了抓到比较纯净的包,我们实现一个简单的 TCP Server,接受客户端的请求并回复。

 
 

func main() { // 监听端口 l, err := net.Listen("tcp", "0.0.0.0:8080") if err != nil { panic(err) } defer l.Close() for { // 接受连接 conn, err := l.Accept() if err != nil { log.Printf("accept err: %s\n", err) continue } go hello(conn) } } func hello(conn net.Conn) { defer conn.Close() buf := make([]byte, 1024) // 读数据 if _, err := conn.Read(buf); err != nil { log.Printf("conn read err: %s\n", err) return } log.Printf("%s\n", string(buf)) // 写数据 if _, err := conn.Write([]byte("hello, xiao ming.\n")); err != nil { log.Printf("conn write err: %s\n", err) return } }

客户端请求:

 
 

echo -n "hello, xiao mei." | nc 81.68.197.93 8080

编辑切换为居中

添加图片注释,不超过 140 字(可选)

使用 wireshark 分析(统计 - 流量图)可以清楚的看到三次握手的过程。

同时也能看到 seq 和 ack 的关系,在握手成功后发送了 len=16 的包后,然后 ack=17 表示序列号在 16 之前的数据都已经正确收到。

注意:ISN 是一个随机数,并不为 0,wrieshark 为了显示更友好,使用了相对序号,在鼠标右键选项中取消即可看到真正的序列号,如:Seq=3503481500。

编辑切换为居中

添加图片注释,不超过 140 字(可选)

状态机

TCP 所谓的面向连接本质就是客户端和服务端的数据结构都各自维护了一个”连接状态“,三次握手期间状态变化如下:

编辑切换为居中

添加图片注释,不超过 140 字(可选)

LISTEN:服务端主动监听一个端口,等待客户端的连接请求

SYN-SENT:发送 SYN 包后的状态

SYN-RECEIVED:收到 SYN 包,且发送了 SYN+ACK 包后的状态

ESTABLISHED:连接建立成功

 
 

# 使用 netstat 命令查看当前系统的 TCP 连接状态 $ netstat -t Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 ubuntu:58824 39.156.66.18:http TIME_WAIT tcp 0 0 localhost:20172 localhost:37276 ESTABLISHED

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值