三次握手彻底弄懂不在怕被挖坑

三次握手四次挥手 在面试过程中经常被提及的话题,回答的深度不同往往会影响面试官对面试者水平的评判 废话不多说直接上干货

TCP链接是什么

用于保证可靠性和流控制机制的信息,包含Socket、序列号以及窗口大小叫做链接。
所以,建立TCP链接就是通信的双方需要对上述三中信息达成共识,链接中的一对socket是由互联网地址标志符和端口组成的,窗口大小主要用来做流控制,最后的序列号是用来追踪通信发起方发送的数据包序列号、接收方通过序列号向发送方确认某个数据包成功接收。

三次握手

三次握手:背景出现在建立TCP链接时,客户端和服务端共发送三个包。三次握手的主要作用就是为了确认双方的接受能力和发送能力是否正常,指定自己的初始化序列号为后边的可靠性传送做准备。就是指定服务器连接端口、建立TCP链接、并同步链接双方的序列号和确认号,交换TCP窗口大小信息。

第一次握手:

客户端给服务端发送一个SYN报文,并指明客户端初始化序列号ISN。此时客户端处于SYN_SEND状态。
首部的同步位SYN=1,初始序列号seq=x,SYN=1的报文段不能携带数据。但要消耗一个序列号。

第二次握手:

服务器收到客户端的SYN报文之后,会以自己的SYN报文作为应答,并且也是指定了自己的初始化序列号ISN(s)。同时会把客户端的ISN+1作为ACK的值,标识自己已经收到了客户端的SYN,此时服务器处理SYN_REVD的状态
在确认报文段中SYN=1,ACK=1,确认好ack=x+1,初始序列号seq=y.

第三次握手

客户端接收到SYN报文之后,会发送一个ACK报文,也是一样把服务器的ISN+1作为ACK的值,标识已经接收到了服务端的SYN报文,此时客户端处于ESTABLISHED状态。服务器收到ACK报文之后,也是处于ESTABLISHED状态,双方建立链接完成。
确认报文段ACK=1,确认好ack=y+1,序号sew= x+1(初始为seq=x,第二个报文段所以要+1),ACK报文段可以携带数据,不携带数据则不消耗序列号。
发送第一个SYN的一端将执行主动打开(active open),接收这个SYN并发回下一个SYN的另一端执行被动打开(passive open)

在socket编程中,客户端执行connect(),出发三次握手
在这里插入图片描述

为什么需要三次握手

接下来介绍下为什么要通过三次握手才可以初始化Socket、窗口大小、初始序列号并建立TCP链接
  1. 通过三次握手才能阻止重复历史连接的初始化
  2. 通过三次握手才能对通信双方的初始化序列号进行初始化
  3. 讨论其他次数握手建立链接的可能性

历史链接

TCP连接使用三次握手的首要原因就是为了阻止历史连接重复初始化造成的混乱问题,防止使用TCP协议通信的双方建立了错误的连接

在这里插入图片描述

情景再现

如果通讯双方通信次数只有两次那么发送一方 一旦发出建立连接的请求之后它就没办法撤回这一次请求,如果在网络状况复杂或者是较差的网络中,发送方连续发送多次连接请求,如果TCP建立连接只能通信两次,那么接收方只能通过选择接收或者是拒绝发送方发起的请求,它并不清楚这一次请求是不是由于网络拥堵早就过期了。
所以TCP选择使用三次握手来建立连接并在连接引入了RST这一控制消息。接收方当收到请求时会将发送方发来的SEQ+1发送给对方,这时由发送放来判断当前连接是否是历史连接。

~ 如果挡墙连接是历史连接,即SEQ过期或超时,那么发送方就会直接发送RST控制消息终止这一次连接
~ 如果当前连接不是历史连接,那么发送方就会发送ACK控制消息,通信双方就会成功建立连接。

使用三次握手和RST控制消息将是否建立连接的最终控制权交给了发送方,因为只有发送方有足够的上下文来判断当前连接是否是有错误或是过期,这也是TCP使用三次握手建立连接的最主要的原因。

初始序列号

另一个使用三次握手的重要的原因就是通信双方都需要获得一个用于发送信息的初始化序列号,作为一个可靠的传输层协议,TCP需要在不稳定的网络环境中构建一个可靠地传输层,网络的不确定性可能会导致数据包的确实和顺序颠倒等问题,常见的问题可能包含:

  1. 数据包被发送多次发送在成数据的重复;
  2. 数据包在传输的过程中被路由或者是其他的节点丢失;
  3. 数据包到达接收方可能无法按照发送顺序;

为了解决上述问题,TCP协议要求发送方在数据包中加入【序列号】字段,有了数据包的序列号,就可以

  1. 接收方可以通过序列号对数据包进行去重
  2. 发送方会在对应数据包之未被ACK时进行重复发送;
  3. 接收方可以根据数据包的序列号对他们进行重新排序;

序列号在TCP连接中有着非常重要的作用,初始化序列号作为TCP链接的一部分也需要在三次握手期间进行初始化,由于 TCP连接通信的双方都需要获得初始化序列号,所以他们其实需要向对方发送SYN控制消息并携带自己期望的初始化序列号SEQ,对方在收到SYN消息之后会通过ACK控制消息以及SEQ+1来进行确认。

在这里插入图片描述

如上图所示,通信双方的两个TCP A/B 分别向对方发送SYN和ACK 控制消息,等待通信双方都获取到了自己期望的初始化序列号之后就可以开始通讯了 ,由于TCP消息头的设计,我们可以将中间的两次通讯集合成一个,TCP B 和TCP A同事发送ACK 和SYN 控制消息,这也就帮我们将四次通讯减少成三次通讯了。
除此之外,网络作为一个分布式的系统,其中并不存在一个用于技术的全局时钟,而TCP可以通过不同的机制来初始化序列号,作为TCP链接的接收方我们无法判断对方传来的初始化序列号是否过期,所以我们需要交由对方来判断,TCP链接的发起方可以通过保存发出的序列号判断链接是否过期,如果让接收方来保存并判断序列号确实是不现实的,这也就强化了便面历史错误链接的初始化。

通信次数

当我们讨论TCP建立链接需要的通信次数时经常会执着于为什么是三次才可以建立链接,而不是两次或四次;讨论使用更多次的通信次数来建立连接往往是没有意义的,因为我们总可以使用跟多的通信次数交换相同的信息,所以使用四次或五次或跟多次数建立连接在技术上是完全可以实现的。

在这里插入图片描述

对于这种增加TCP连接通信次数的问题往往没有讨论的必要性,我们追求的其实是更少的通信次数完成信息的交换,这也就是为什么我们在以上说的使用两次握手没有办法建立TCP连接,使用三次握手是建立连接所需的最小次数。

总结

这篇文章讨论了为什么建立TCP连接需要经过三次握手,TCP连接定义就是用于保证可靠性和流程控制机制的数据,包括Socket、序列号和窗口大小。
TCP建立连接时通过三次握手可以有效的避免历史错误链接的建立,较少通信双方不必要的资源消耗,三次握手能够帮助通信双方获取初始化序列号,他们能够保证数据包传输时不重不丢包,海能保证他们的传输顺序,不会因为网络传输问题发生混乱,到这里不适用两次握手 和四次握手的原因已经非常清楚了;

两次握手:无法避免历史错误链接的初始化,浪费接收方的资源
四次握手:TCP协议的设计可以让我们同时传递ACK和SYN两个控制信息,较少通信次数,所以不需要使用更多的通信次数传输相同的信息;

文章参考

https://draveness.me/whys-the-design-tcp-three-way-handshake/
https://zhuanlan.zhihu.com/p/86426969

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值