TCP相关知识

三次握手

三次握手

客户端回合-第一次握手

  • SYN=1 (同步标志, Synchronize)
  • seq=x

服务器回合-第二次握手

  • SYN=1
  • ACK=1 (确认标志, Acknowledgement)
  • ack=x+1 (Acknowledgement Number,收到的序号+1,下一个预期的序列编号)
  • seq=y

客户端回合-第三次握手

  • ACK=1
  • ack=y+1
  • seq=x+1

注意

  • 大写的ACK和SYN是标志位,也就是flag,也就是只有0或1,表示一种状态
  • SYN只在前两个握手里存在,是一种建立连接的意愿,双方互相了解对方的意愿之后就不用再发了
  • 仅当ACK=1时确认号字段才有效。 当ACK=0时,确认号无效。TCP规定:在连接建立后,所有传送的报文段都必须把ACK置为1
  • seq表示一个TCP包的序号,可以看出客户端和服务器各自有自己的序号,这样双方就能知道对方发来的数据的顺序
  • 小写的ack为自己确认收到的最后一TCP包的序号+1,告知对方我想要的下一个包的开始是什么

形象一些:

客户端:

SYN=1 ---> 我想要建立TCP连接,请问可以吗

seq=x ---> 这条信息是我发的第x条信息

服务器:

SYN=1 ---> 我同意和你建立TCP连接

ACK=1 ---> 这条信息包含确认信息

ack=x+1 ---> 我收到的你发来的最后一条信息是第x条,下一条信息你应当从x+1开始发

seq=y ---> 这条信息是我发的第y条信息

客户端:

ACK=1 ---> 这条信息包含确认信息

ack=y+1 ---> 我收到的你发来的最后一条信息是第y条,下一条信息你应当从y+1开始发

seq=x+1 ---> 这条信息是我发的第x+1条信息

另外,所谓的握手,我认为是某一方发送的消息到达对方的那一刻称为握手。这表明我发送了消息,你收到了消息,我们两个共同知晓了这条消息,像握手一样。在图中就是箭头到达对方那一刻。

四次挥手

四次挥手

客户端回合-第一次挥手

  • FIN=1 (Finish)
  • seq=u

服务器回合-第二次挥手

  • ACK=1
  • ack=u+1
  • seq=v

服务器回合-第三次挥手

  • FIN=1
  • ACK=1
  • ack=u+1
  • seq=w

客户端回合-第四次挥手

  • ACK=1
  • ack=w+1
  • seq=u+1

注意

  • 所谓的服务器和客户端只是一个名字,不论是建立连接还是断开连接,我们都认为率先发起的为客户端,被动接受的为服务器
  • 第二和第三次挥手都是服务器回合,服务器首先回复表示收到了数据,然后传送剩余的没传完的数据,然后准备关闭连接
  • seq=w和seq=v之间的数据就是剩余的没传完的数据,同时,这两次回复的确认号都是ack=u+1
  • 由于客户端发起的关闭连接请求,所以认为他数据已经传输完毕,所以在第二和第三次挥手之间不传输数据

形象一些,就像你妈喊你吃饭,而你在打游戏。

妈妈(客户端) 你(服务器) 类比
“吃饭了” 客户端请求关闭连接
“来了”,但没有动 服务器收到关闭连接的请求并回复
赶紧找到游戏的存档点并保存 服务器传输剩下的没传完的数据
“来了”,并走向厨房,“今天中午吃什么” 服务器的第三次挥手,确认关闭连接
“面条。快点吃吧,饭都凉了” 客户端确认自己收到了服务器的“确认关闭连接”

中间的两次“来了”都是在确认妈妈第一次喊的“吃饭了”。

那么,基于上面的类比,解释客户端TIME_WAIT状态的意义是什么?

为了防止你没有听到“面条”这个回答。如果你没有听到,你会再问一遍,直到听到答案。

放到网络环境里就是:

第四次挥手时,客户端发送给服务器的ACK有可能丢失,TIME_WAIT状态就是用来重发可能丢失的ACK报文。如果Server没有收到ACK(上次自己发的消息没有被确认,他会认为自己的消息丢了,所以重发上次的消息),就会重发FIN,如果Client在2MSL的时间内收到了FIN,就会重新发送ACK并再次等待2MSL,防止Server没有收到ACK而不断重发FIN。

MSL(Maximum Segment Lifetime),指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

TCP如何保证有序

(1)为了保证数据包的可靠传递,发送方必须把已发送的数据包保留在缓冲区
(2)并为每个已发送的数据包启动一个超时定时器
(3)如在定时器超时之前收到了对方发来的应答信息(可能是对本包的应答,也可以是对本包后续包的应答),则释放该数据包占用的缓冲区;
(4)否则,重传该数据包,直到收到应答或重传次数超过规定的最大次数为止。
(5)接收方收到数据包后,先进行CRC校验,如果正确则把数据交给上层协议,然后给发送方发送一个累计应答包,表明该数据已收到,如果接收方正好也有数据要发给发送方,应答包也可方在数据包中捎带过去。

参考

TCP如何保证发送的报文是可靠有序的_tcp如何保证有序_小明喜欢写bug的博客-CSDN博客

posted @ 2023-02-24 15:35  roadwide  阅读(20)  评论(0编辑  收藏  举报