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

互联网文章 文章 2022-07-15 13:32 380 0 全屏看文

AI助手支持GPT4.0

前言

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

通俗版

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

细节版

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

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

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

控制位:

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

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

由于上述报文都未携带数据,即 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: %sn", 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: %sn", err)    return  }  log.Printf("%sn", string(buf))  // 写数据  if _, err := conn.Write([]byte("hello, xiao ming.n")); err != nil {    log.Printf("conn write err: %sn", err)    return  }}

客户端请求:

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

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

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

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

握手包源文件下载地址

状态机

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

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

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

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

ESTABLISHED:连接建立成功

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

参考

图解TCP/IP(第5版)

计算机网络(第7版)谢希仁

酷壳 - TCP 的那些事儿(上)

-EOF-

AI助手支持GPT4.0


国内超级便宜服务器

摸鱼人热门新闻聚合

钻级赞助商 我要加入

开发者在线工具

第三方支付技术请加QQ群

相关文章
SpringBoot集成markdown实现文档管理
单引号和双引号
SpringBoot集成markdown实现文档管理
SpringBoot集成markdown实现文档管理
随便看看
教育科技公司申请微信支付被拒绝? 4810
微信公众号免300认证教程 5901
小程序已经上线,作为管理员无法在小程序数据助手查看数据? 5308
小程序广告组件通过审核,但是小程序内没有显示广告? 5080
企业微信通讯录账号被管理员误/恶意删除,怎么办? 9582
问题? 9061
如何快速搭建抽奖助手小程序(无需代码知识) 6188
许涛 大哥在吗, 要解冻小程序的时候提示信息主体不一致, 能帮忙看下吗? 7481
小程序搜一搜全称搜索不显示 麻烦解决一下!谢谢 6802
我的小程序广告收款主体是个体工商户,每个月邮寄两次发票很是麻烦,我年底的时候打包邮寄一次可以么? 6135