关于问题“TCP为什么要三次握手,而不是两次”的个人见解

最近在看面经,看到有一个问题是“TCP为什么要有第三次握手?”,网上有一部分关于这个问题的答案是谢希仁写的《计算机网络》里面说的那样:

主要是为了防止已经失效的连接请求报文段突然又传送到了B而产生的错误,假设客户端A第一个连接请求报文段没有丢失,但是在网络中滞留了,以致延误到连接释放后的某个时间才到达服务端B,本来是一个早就失效的报文段,服务端B收到后以为客户端A又发出一次新的连接。于是向A发出确认报文段,同意A的请求,建立连接。假如没有最后一次的握手,那么只要B发出ACK报文确认,连接就成功建立了,但是实际上A并没有再次连接B的意愿,因此不会回应B的确认报文,也不会向B发送数据。但是B却以为连接已经建立了,并一直等待A发送数据。服务端B的许多资源就白白浪费。

 但是这个回答并没有答出为什么需要第三次握手的核心部分,个人认为TCP建立连接是三次握手而不是两次握手的最核心原因是为了保证双方的接收和发送能力正常,TCP相对UDP来说有一个特点是可靠,而三次握手四次挥手机制恰巧是可以体现出TCP可靠传输的一个理由,下面贴上一张TCP建立连接三次握手的老图:

  • 客户端A发送连接请求,第一步发送请求报文,SYN位置为1,同时选择一个序列号x,TCP规定SYN报文段不能发送数据,但是需要消耗一个序列号,发送后,此时客户端A的TCP进程进入SYN-SENT(同步已发送状态)
  • 服务器端B接收到请求报文后,如果同意连接,则向A发送确认。在确认报文中吧SYN跟ACK位都置为1,同时消耗一个序列号为y,同样也不能携带数据,ack为x+1,表示序号x(包括x)之前的报文已经收到。此时TCP服务器进程进入SYN-RCVD状态。
  • TCP客户端进程收到服务器B发送的确认报文后,还需要给服务器B发送确认报文。确认报文段的ACK置为1,确认号为 ack = y+1,而自己的序号seq = x+1。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序列号,下一个数据报文段的序列号仍然是seq = x+1。此时TCP连接已经建立完成,A进入ESTABLISHED(连接已建立)状态。

一般来说 :

  • 第一次握手:当第一次握手成功之后,服务端就知道了客户端的发送能力是正常的,而自己的接收能力也是正常的
  • 而第二次握手:服务端对客户端发送的报文的应答,ack的值是源自客户端第一次握手发送的报文的seq序列号+1,而客户端正常收到该应答后,它就知道自己的发送能力正常,服务端的接收能力正常,服务端的发送能力正常
  • 第三次握手:第三次握手是客户端对服务器端的应答,ack的值是源自第二次握手服务端发送报文的seq序列号+1,而服务端收到该响应报文之后,才知道自己的发送能力正常,知道客户端的接收能力正常。

正是第三次握手才让双方清楚自己的接收能力和发送能力正常,在这样的前提下才会是可靠传输 ,假如没有第三次握手,那么服务端就不会知道对方客户端是否能够给自己在第二次握手的请求作出响应。

而书本《计算机网络》里面对于TCP建立连接第三次握手的回答个人是觉得是基于AB双方已经成功建立过连接的情况下,第三次握手的另外一个作用是防止已经失效的连接请求报文段突然传输到接收方而产生的的错误,那假如AB双方是第一次建立TCP连接,那么第三次握手的作用更重要的是保证双发的接收发送能力正常,

以上是个人对于该问题的的一些见解,如果有说的不对的地方,请各位大佬斧正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值