tcp序列号为什么是随机的_让你真正知道Tcp的三次握手和四次挥手

在了解TCP之后我们需要先了解TCP Header的相关存储信息,这样我们能更好理解其过程,而不是死记硬背流程(网上一堆流程 问:吃饭了了吗?答:吃了。。。。。。)

1.TCP Header结构:

672fcf4f071d48d49470b037314677c1

Header

我们看到其实Header中的Data是分段的,这也需要seq和ack的帮助来保证服务端收到数据的连续性;

上图中Sequence number 和 Acknowledgement number是实现握手机制的保障

2.名词解释:

SYN:代表请求创建连接,所以在三次握手中前两次要SYN=1

FIN:表示请求关闭连接,用于四次挥手

ACK:代表确认接受,在回应的时候都会加上ACK=1,表示消息接收到了,并且在建立连接以后的发送数据时,都需加上ACK=1,来表示数据接收成功。

seq(Sequence number ):随机生成序列号,当发送一个数据时,数据是被拆成多个数据包来发送,序列号就是对每个数据包进行编号,这样接受方才能对数据包进行再次拼接。

ack(Acknowledgement number):这个代表下一个数据包的编号,这也就是为什么第二请求时,ack是seq+1,

注意:这里ACK和ack千万tm不要混淆

3.认识seq(Sequence number)和ack(Acknowledgement number)

Sequence number(seq)

当开始一个 TCP 会话时,此时 SYN 位为 1(表示需要建TCP连接),会生成一个随机的 Sequence number_A,表示我希望接收到的回复是 Sequence number_A+1,这样服务端回复的ack如果不是 Sequence number_A+1 ,则说明连接没有正常建立, 后续使用 Sequence number 则从 Sequence number_A + 1 开始。

--------------非重点内容------------

其他时候,则表示为 data 部分第一位的位置,值为此位数据的 Sequence number ,即基于初始 Sequence number + 1 + offset。

其实很好理解,我们先抛开第一次生成的 Sequence number,后续的 TCP 头中的 Sequence number 都指的是 data 部分第一位的序号。比如:

我这次发送的 Sequence number 为 100,数据长度为 100,

那么我下一次发送的 Sequence number 就应该是 200,再假定数据长度为 50,

如果要进行第三次发送,那么 Sequence number 的值应为 250。

下面的图简单的表明了发送两个连续的 segment 的 Sequence number 变化情况,忽略了TCP头,TCP头 并不计入 Length

-----------非重点内容结束----------

Acknowledgement number(ack)

回复收到的最大 Sequence number + 1,表示期望收到的 Sequence number 的值。

4 三次握手过程概述(内容部分摘自马士兵老师分享)

了解上面的内容,我们再分析过程,简单很多,TCP连接三次握手的过程如下,为了方便描述:

SEQ_NUM 代表 TCP header 中的 Sequence number

ACK_NUM 代表 TCP header 中的 Acknowledgment number

DATA_LEN 代表 segment 中 data 的长度

SYN(1) ACK(0) SEQ_NUM(0) ACK_NUM(0) DATA_LEN(0)    ====>                                                   <====  SYN(1) ACK(1) SEQ_NUM(100) ACK_NUM(1) DATA_LEN(0)SYN(0) ACK(1) SEQ_NUM(1) ACK_NUM(101) DATA_LEN(0)  ====>
  • 连接发起方将 SYN 位设置为1,然后随机生成一个 SEQ_NUM_A,发送给被发起方。
  • 被发起方回复 ACK(1) ACK_NUM(SEQ_NUM_A+1),同时也需将 SYN 位设置为1,然后自己也随机生成一个 SEQ_NUM_B。
  • 连接发起方收到上个 segment 后,回复 ACK(1) ACK_NUM(SEQ_NUM_B+1),当被发起方收到这个 segment 后,连接建立成功。

5 可能存在的疑问

1、为什么要强调 Sequence number 和 Acknowledgement number?

假设同样是三次握手,但是很简单:

SYN(1) ACK(0)  ====>               <====  SYN(1) ACK(1)SYN(0) ACK(1)  ====>

看起来没问题,但实际上由于网络传输是不可靠的,如果没有 Sequence number 我们无法保证此时收到的 segment 的顺序性,也无法得知是否丢失了某个 segment。同样是一个 SYN(1) ACK(1) segment,它有可能是上一次建立连接时被发送方误认为已经丢失的 segment,甚至更特殊的情况。

在数据传输的过程中也是如此,被重发的 segment,丢失的 segment,连续发送的 100 个 segment 如果没有 Sequence number 作为保障,他们到达(或者到达不了)接收方的排列组合方式可能千奇百怪。

2、那么在 Sequence number 和 Acknowledgement number 的保障下,如何保证自己的消息被对方收到呢?

这个其实很好理解,实际上就是自己发送出去的这部分 Sequence number 被 ack 了即可,即:一去一回(实际上可以多去一回,或者可能一去多回,但这里只说最简单的情况)。

SEQ_NUM(100) DATA_LEN(100)    ====>                              <====   ACK(200)

如果没有收到对方的 ack,或者收到的 ack 非此 segment 的 ack,则代表对方没有收到自己的消息,比如下面这个例子,此时我们能得知,对方没有收到或者暂时还没收到我们发送过去的第二个 segment。

此时也可以区分出收到的 segment 是否属于本次连接,因为在建立连接后我们会生成一个新的 Sequence number。

SEQ_NUM(100) DATA_LEN(100)    ====>                              <====   ACK(200)SEQ_NUM(200) DATA_LEN(100)    ====>                              <====   ACK(200)

3、这就很好理解 TCP 连接握手为什么是三次了。

发起连接方发出SYN,并收到ACK,这就是两次网络传输了。

同样被连接方也发出SYN,且等待对方回复,这也是两次网络传输。

加起来难道不是四次吗?实际上被连接方将对连接方 SYN(1) 的回复和自己 SYN(1) 的请求合并了,所以建立一个 TCP 连接最少只需要经过三次网络传输。

4、那为什么 TCP 断开连接需要四次,而不是三次?

发起断开方发出FIN,并收到ACK,这就是两次网络传输了。

同样被断开方也发出FIN,且等待对方回复,这也是两次网络传输。

同样的逻辑分析下来,实际上也可以仅经过三次传输就断开此次连接,但为什么我们会说四次挥手呢?这是因为如果在收到FIN时,彼时还有数据未传输完,则先回复关于 FIN 的 ACK,告知对方我已经知道你要断开了。则等待传输完毕后,被断开方再发送 FIN,告知自己也已经可以断开连接。

但实际上完全可以是“三次挥手”,如果收到 FIN 时,已经没有数据要传输,则是“三次挥手”。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值