性能文章>TCP-三次握手>

TCP-三次握手原创

1年前
407047

TCP-三次握手

最近对计算机网络蛮感兴趣的,借着这股劲,来系统研究研究 TCP 协议。

先来个经典的三次握手问题

一问,为什么要三次握手?

首先 TCP 协议底层是 IP层,IP层 本身是不可靠的

TCP 协议的出现,就是要创建一个可靠的协议,区别于 UDP协议

TCP 为了提供可靠的服务,得先建立起连接,保证通讯双方至少是可达的

这个过程就像是打电话一样,如果对方都没有接听你的电话,你一直在电话这头说话,谁能听得到呢

图文详解

建立一条端对端的连接

主动发起连接的端称客户端

被动接受连接的端称服务端

先上一张图,看看客户端发起三次握手后两端的状态变更情况:

image-20230129200818316

客户端状态变更

  1. 开始时是 关闭的状态「CLOSED
  2. 当客户端向服务端发送同步请求的时候,状态变为 同步发送状态「SYN_SENT
  3. 当接受服务端的响应时,状态变更为 已建立状态「ESTABLISHED

服务端状态变更

  1. 开始时也是 关闭的状态 「CLOSED
  2. 当服务端唤起系统调用 bind、listen 后状态变更为 监听状态「LISTEN
  3. 当服务端接受到客户端的同步请求后,状态变更为 同步接收状态 「SYN_RCVD
  4. 当服务端接受到客户端的ACK响应后,状态变更为 已建立状态「ESTABLISHED

注: CLOSED 是一种假想的状态,所以在使用 netstat 命令查看state的时候并不能展示这种状态

触发三次握手

如何触发三次握手呢?有很多的方法

比如你可以通过 Java 网络编程编写一个服务端 ServerSocket,监听特定的端口

再编写一个客户端连接这个服务端

这里介绍一种更快捷的方法

  1. 打开命令行,输入下面的命令,创建一个服务端
nc -l 9999
  1. 再打开另一个命令行,连接服务端
telnet 127.0.0.1 9999

打开 Wireshark就可以抓到相应的TCP包了

在 filter 输入 tcp and tcp.port == 9999 ,只抓取 tcp协议并且tcp的端口号为 9999 的网络包

image-20230201191715687

不熟悉 TCP 协议的同学看到上图这一堆的数值可能还是会有点迷糊

那就先介绍一下TCP头的结构

image-20230130225650974

TCP 头部结构的大小为20到60个字节,按照顺序有

  • 16位的源端口号 :表示该包从哪个端口发来的

  • 16位的目的端口号 :表示该包要发往的目的端口号

  • 32位的序列号 :因为TCP是面向字节流的,这个序列号表示这个包的第一个字节在字节流中的序号

  • 32位的确认号 :发送确认(ACK)一端期望下次接收的序列号

  • 4位首部长度 :指TCP头部长度为多少个32位

  • 6位保留

  • 6位标志位

    1. URG : urgent 紧急标志 ,标记该包优先级高
    2. ACK :ackownledegment 应答响应标志
    3. PSH :push 立即发送包,不缓存
    4. RST :reset 重置连接,表示该连接不再接受请求
    5. SYN : syn 发送同步包,建立同步连接
    6. FIN :fin 断开连接
  • 16位窗口大小 :接受方的接受窗口大小,对发送方进行流量的控制

  • 16位校验和

  • 16位紧急指针 :和 URG 标记一起使用,URG标志位为1的时候,这个值才生效,这个值为偏移量,表示区间内的数据为紧急数据 [seq,seq+offset]

  • 可选字段,如最大报文长度MSS

接着分析三次握手的报文

  1. 第一个报文,看上图 NO为 402 的报文

image-20230201193758682

这是由客户端发送到服务端的报文

  • 序列号为 3116214529
  • 确认号为 0
  • 来源端口号 55848
  • 目的端口号 9999
  • flags 标志只有 SYN 是置为1的
  • 窗口大小为 65535
  • options 有MSS,值为16344
  1. 第二个报文

image-20230201192414880

这个报文是从服务端发送给客户端的

  • 序列号为 940657738
  • 确认号为 3116214530,等于第一个报文的 序列号+1
  • 来源端口号 9999
  • 目的端口号 55848
  • flags 标志 SYN、ACK 是置为1的
  • 窗口大小为 65535
  • options 有MSS,值为16344
  1. 第三个报文

image-20230201192841600

这个报文是从客户端发送给服务端的

  • 序列号为 3116214530
  • 确认号为 940657739,等于第二个报文的 序列号+1
  • 来源端口号 55848
  • 目的端口号 9999
  • flags 标志 ACK 是置为1的
  • 窗口大小为 6379

三次握手是 TCP 建立连接的过程,需要关注的点在于报文的flags变化,window,mss 等

点赞收藏
分类:标签:
MinXie
请先登录,查看4条精彩评论吧
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步

为你推荐

日常Bug排查-连接突然全部关闭

日常Bug排查-连接突然全部关闭

7
4