简介

接前文 协议簇:TCP 解析: 基础, 我们这篇文章来看看 TCP 连接建立的过程,也就是众所周知的”三次握手“的具体流程.

系列文章

协议簇:TCP 解析:基础
协议簇:TCP 解析:建立连接
协议簇:TCP 解析:连接断开
协议簇:TCP 解析:Sequence Number
协议簇:TCP 解析:数据传输

三次握手

最普通的 TCP 握手流程如下图:

下面描述中,序列号对应于上图中的行号.

  1. 初始状态时,TCP A 处于连接关闭状态, TCP B 处于监听状态. 也就是通常所说的 A 时 TCP 客户段,B 是服务端.
  2. A 发送 SYN 给 B, 并附有 SEQ, 请求建立 TCP 连接。
    A 发送 SYN 后,状态切换为 SYN-SENT, B 接收到 A 发送的 SYN 后状态切换为 SYN-RECEIVED.
  3. B 收到 A 的 SYN 之后,发送它的 SYN(注意,这里 A 和 B 的 SEQ 是相互独立的 ),并附上 ACK 标记用以表明 B 收到了 A 的 SYN 包。
    这里注意: B 发送的 ACK 的值为 101,它代表 B 收到了序列号为 100和100之前的所有字节数据,并告诉 A 自己期待下一次收到序列号以101开始的数据.
    A 在接收到 B 的 SYN 之后,状态转化为 ESTABLISHED.
  4. A 收到 B 的 SYN 之后, 需要发送 ACK 给 B 告诉 B 自己收到了它的 SYN + ACK 包.
    这里注意:A 发送的ACK的值为 301, 原因是 B 的 SYN 中的 SEQ 是 300. A 发送的 SEQ 是 101,原因是上一次的请求中序列号已经增长到了 100. 下一个可用的序列号就是 101.
    在B接收到 A 的 ACK 之后,它的状态切换为 ESTABLSHED. 至此,三次握手已经完成,一个 TCP 连接已经成功建立。
  5. 在这条 TCP 连接上可以进行数据传输.

在了解了基本的流程之后,我们来使用 wireshark 包应用以下所学:

如下图,忽略其中的黑色记录,一共四条记录,对应于上图中的 2-5.

接下来,我们详细看看每条记录

客户端 SYN

这是建立 TCP 连接三次握手中的第一次

这张图涵盖的信息很多,全部字段的含义在前文中已经描述过,这里我们仅仅关注个别字段.

  1. Flags 字段中 SYN 标记为 1. 表明当前 TCP 包是一个 SYN 包. 首先发送这个数据包的 TCP 段为请求建立 TCP 连接的端点.
  2. Sequence Number 字段的值为 2292773402. Wireshark 为了方便我们查看,引入另外一个字段 relative sequence number. 这个字段的值是基于 initial sequence number 计算所得. 正如前文 TCP 基础中所说,当当前 TCP 包是一个 SYN 包时,Sequence number 就是 Initial Sequence Number, 因此 这里 relative sequence number 的值是 0.
服务端 SYN + ACK

这是建立 TCP 连接三次握手中的第二次

  1. Flags 字段中 SYN 和 ACK 字段均为 1
  2. Sequence Number 字段的值为 4127119125 (前面说过,客户端的 SEQ 和 服务端的 SEQ 是独立的,他们之间没有联系), Relative Sequence Number 为 0.
  3. Acknowledge Number 字段的值为 2292773403. 客户段发送的 SYN 中 的 SEQ 值是 2292773402. 序列号 2292773403 告诉客户端 2292773403以及之前的所有数据已经收到。 在接收到这个响应之后, 客户端便可以确信服务段收到了自己发送的 SYN 包.
客户端 ACK

这是建立 TCP 连接三次握手中的第三次

  1. Flags 字段 ACK 为 1
  2. Sequence Number 的值为 2292773403. 这个值于服务端发送给我们 SYN+ACK 包中的 ACK 值相同.
  3. Acknowledge Number 的值为 4127119126. 这里需要注意服务第发送的 SYN+ACK 包中的 SEQ 的值为 4127119125.

至此,这个 TCP 连接成功建立。

特殊情况: 双方同时请求建立连接

在一个 TCP 建立成功之前,连接双方是没有任何关于对方的信息的。因此,存在一种巧合,那就是双方同时发起建立TCP连接的请求. 这里我们来看一下这个特殊情况.

图中 "… " 用来表示该数据包正在网络上传输,对方还未收到.

注意,这里图中虽然对数据包进行 1-7 的编号,但是对于双方任何一方,都是独立的. 也就是说,接收数据的先后是不确定的,有可能 B 先接收到 A 的包,也有可能 A 先接受到 B 的包。 这里我们并没有明确的指定哪一方为 服务端,哪一方为客户端,因此这里的结论都是成立的.

  1. 初始状态下,双方均处于 CLOSED 状态. 存在这种可能: 某一时刻双发同时发送自己的 SYN 给对方,请求建立一条 TCP 连接.
  2. 在某一时间点,A 发送 SYN 到 B 请求建立 TCP 连接. 此时,A 的状态切换为 SYN-SENT
  3. B 在未收到 A 发送的 SYN 包时,发送了自己的 SYN 给 A,请求建立一条连接. 此时,B 的状态也切换为 SYN-SENT. 在接收到 B 发送的 SYN 之后,A 的状态切换为 SYN-RECEIVED.
  4. 此时,A 发送的 SYN 到达 B 端。B 收到了 A 发送的 SYN 包,状态切换为 SYN-RECEIVED.
  5. 在第三步之后,A的状态一旦变成SYN-RECEIVED, 他就需要发送对应的 SYN+ACK 给 B,以确认自己接收到了 B 发送的 SYN. 并将自己的状态切换为 ESTABLISHED. 这里注意,它发送完 SYN+ACK 之后,只是单方的进入 ESTABLISHED 状态,对应状态依然为 SYN-RECEIVED.
  6. 在第四步之后, B的状态一旦变成SYN-RECEIVED,它也要发送 SYN+ACK. 并切换状态为 ESTABLISHED。
  7. B 收到 A 发送的 SYN+ACK。 至此,双方均进入 ESTABLISHED 状态,一个连接已然建立成功.

特殊情况: 旧的重复的 SYN

TCP 协议的设计为三次握手的一个很重要原因就是处理旧的重复的SYN包

RFC793 原文: The principle reason for the three-way handshake is to prevent old
duplicate connection initiations from causing confusion

这里我们就来看看它是如何处理的。

看下图的 TCP 包流程:

  1. 初始状态下, A 为客户端,处于 CLOSED 状态。 B 为服务端,处于LISTEN状态
  2. 某一时刻,A 发送 SYN 给 B,请求建立 TCP 连接
  3. B 在收到 A 刚刚发送的 SYN 包之前, 收到了一个旧的重复的来自 A 的 SYN.
  4. 对于 B 段来说,在收到来自 A 的 SYN 包时,它是不知道那是一个旧的重复的 SYN 包的,因此它就想就受到一个普通的 SYN一样响应这个 SYN 包. 发送 SYN+ACK 进行确认.
  5. A 端收到来自 B 段的 SYN+ACK, 发现其中的 ACK 字段的值不正确. 因为自己发送的 SYN 中 SEQ 值为 100,响应SYN+ACK包中的 ACK的值应该为 101,但是它收到的 SYN+ACK包中的ACK的值却是91. 在收到这个非法的SYN+ACK之后,A 段发送 RST,并附上错误的SEQ序列号. B 端收到A发送过来的 RST 之后,便得知 A 重置了上一个SYN想要建立的TCP连接,B 段重置所有关于为上一个 SYN 所记录的状态,并重新回到 LISTEN 状态.
  6. 对于 TCP 协议来说,数据是不会丢失的,也就是说 B 段迟早会收到 A 发送的 SYN(SEQ=100). B 端收到 A 的 RST 之后,状态切换到了 LISTEN之后, A 发送 SYN(SEQ=100)到达,此时B依然回像通常情况一样. 如果 SYN(SEQ=100)到达 B 段早于 A 发送的 RST,将会是一个更复杂的情况,涉及到双发均发送 RST 的场景. 这里能力有限,略掉.
  7. B 在收到正确的 SYN+ACK之后,发送自己的 SYN 给 A
  8. A 在发送自己的 SYN+ACK给B,这样之后,一个 TCP 连接成功建立.

如果剔除上述流程中 3-5,我们会发现这就是一个普通的 TCP 连接的三次握手流程. 厉害的地方在于,引入三次握手建立连接的机制,TCP 可以优雅的处理掉由于网络不可靠所导致的非法SYN的数据包。 厉害

协议簇:TCP 解析: 建立连接相关推荐

  1. 网络协议 (五) TCP握手建立连接

    一.握手策略 为了可以准确的将数据准确无误地送达目标主机,所有基于 TCP 实现的协议,都需要先完成 TCP 协议的三次握手策略. 1. 首先我们需要了解一下图中提到的几个标志符: 1.序号seq s ...

  2. 在哪里查看计算机配置的网络协议簇,tcp/ip协议簇

    TCP/IP协议簇是Internet的基础,也是当今最流行的组网形式.TCP/IP是一组协议的代名词,包括许多别的协议,组成了TCP/IP协议簇.其中比较重要的有SLIP协议.PPP协议.IP协议.I ...

  3. ActiveMQ源码解析 建立连接

    作为一个消息中间件,有客户端和服务端两部分代码,这次的源码解析系列主要从客户端的代码入手,分成建立连接.消息发送.消息消费三个部分.趁着我昨天弄明白了源码编译的兴奋劲头还没过去,今天研究一下建立连接的 ...

  4. TCP/IP 建立连接的过程

    在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接. 第一次握手:建立连接时,客户端发送连接请求到服务器,并进入SYN_SEND状态,等待服务器确认: 第二次握手:服务器收到 ...

  5. 协议簇:TCP 解析: 连接断开

    简介 接前文 协议簇:TCP 解析: 建立连接, 我们这篇文章来看看 TCP 连接断开的过程,也就是众所周知的"四次挥手"的具体流程. 系列文章 协议簇:TCP 解析:基础 协议簇 ...

  6. 协议簇:TCP 解析:TCP 数据传输

    简介 前面,我们分别介绍了 TCP 基础知识以及连接的建立和关闭,以及最重要的 Sequence Number 的概念. 本篇文章,我们来介绍一下 TCP 如何传输数据. 系列文章 协议簇:TCP 解 ...

  7. 协议簇:TCP 解析: Sequence Number

    简介 序列号(Sequence Number) 是 TCP 协议中非常重要的一个概念,以至于不得不专门来学习一下.这篇文章我们就来解开他的面纱. 在 TCP 的设计中,通过TCP协议发送的每个字节都对 ...

  8. 协议簇:TCP 解析: 基础

    简介 本文我们将从 RFC 学习一下 RFC793 中描述的 TCP 协议. 这将区别于通常讲解计算机网络书籍中所描述的 TCP. 但他们必然是相统一的,不会互相冲突. 系列文章 协议簇:TCP 解析 ...

  9. TCP/IP 协议简单分析(建立连接握手过程)

    原文:http://hi.baidu.com/wuguoyana/blog/item/38c04d3bcf047ce43a87ce55.html 首先TCP和IP是两种不同的协议,它们来七层网络模型中 ...

最新文章

  1. python3网络编程中semaphore用法_python3 进程信号量semaphore
  2. .NET Core微服务开发选项
  3. Actor-ES框架:Ray--事件(Event)编写说明
  4. JM8.5中的7种宏块模式问题 - zhoujunming的专栏 - CSDN博客
  5. .[转] 读十年书,不如读懂这百句话
  6. Android APP漏洞自动化静态扫描检测工具-Qark
  7. 腾讯轻量云FREEBSD11.1安装panabit cloud
  8. w ndows10家庭版和企业版谁好用,Windows10系统哪个版本好?Win10家庭版和专业版的区别介绍...
  9. u盘只有盘符没有容量打不开-U盘无法识别,无法格式化
  10. PD协议芯片TYPE C接口支持快充诱骗
  11. React控制台警告Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until
  12. 广州麦仑 全面亮相2022身份识别技术大会及第十七届SDS
  13. DFT与FFT运算效率的比较
  14. 在vue、html中手动写日期格式化转换为“yyyy-MM-dd hh:mm:ss”
  15. 三星Galaxy S21 FE和三星Galaxy S21对比
  16. html课程表斜杠,Word功课表斜线怎么做
  17. 爬虫日记(108):Twisted:使用后悔药
  18. html 精美list,HTML DOM DList用法及代码示例
  19. GIS开发:nginx发布常用数据
  20. 面试题准备(二十六):form 表单

热门文章

  1. 基于深度学习的IRS辅助MIMO通信系统的CSI压缩及恢复研究
  2. JavaWeb笔记:CSS总结
  3. Python+Selenium基础篇之2-打开和关闭火狐浏览器
  4. LUGOU P3907 圈的异或
  5. 单例设计模式之安全的懒汉式
  6. hdu 1257最少拦截系统(贪心)
  7. mysql 其他引擎
  8. 使用IOUtils和FileUtils
  9. linux网络编程——webserver服务器编写
  10. java 仿qq登录界面7.1_安卓开发学习笔记(七):仿写腾讯QQ登录注册界面