面试重点:TCP 为什么是三次握手,而不是两次或四次?

TCP (Transmission Control Protocol) 传输控制协议

TCP连接握手,握的是啥?通信双方数据原点的序列号,确认双方的发送能力和接收能力,工作在传输层

位码即tcp标志位,有6种标示,SYN(synchronous建立联机)、ACK(acknowledgement确定)、PSH(push传送)、FIN(finish结束)、RST(reset重置)、URG(urgent紧急)seq(Sequence number顺序号码)、ack(Acknowledge number确定号码)

一、TCP三次握手过程

开始,客户端A和服务器B都为CLOSED状态。在通信开始前,双方都得创建各自的传输控制块(TCB)。

服务器B创建完TCB后遍进入LISTEN状态,此时准备接收客户端A发来的连接请求。

第一次握手

客户端A向服务器B发送连接请求报文段。该报文段的头部中SYN=1,ACK=0,seq=x。请求发送后,客户端A便进入SYN-SENT状态。

1:SYN=1,ACK=0表示该报文段为连接请求报文。

2:x为本次TCP通信的字节流的初始序号。

TCP规定:SYN=1的报文段不能有数据部分,但要消耗掉一个序号。

第二次握手

服务器B收到连接请求报文段后,如果同意连接,则会发送一个应答:SYN=1,ACK=1,seq=y,ack=x+1。该应答发送完成后便进入SYN-RCVD状态。

1:SYN=1,ACK=1表示该报文段为连接同意的应答报文。

2:seq=y表示服务器B作为发送者时,发送字节流的初始序号。

3:ack=x+1表示服务器B希望下一个数据报发送序号从x+1开始的字节。

第三次握手

当客户端A收到连接同意的应答后,还要向服务器B发送一个确认报文段,表示:服务器B发来的连接同意应答已经成功收到。

该报文段的头部为:ACK=1,seq=x+1,ack=y+1

客户端A发完这个报文段后便进入ESTABLISHED状态,服务器B收到这个应答后也进入ESTABLISHED状态,此时连接的建立完成!

细节:
前两次握手SYN报文不能携带数据,但要消耗掉一个序号。
第三次 握手 ACK报文段可以携带数据,但如果不携带数据则不消耗序号。
凡是需要对端确认的,一定消耗TCP报文的序列号。

状态详解: 

         CLOSED:表示关闭状态/初始状态

         LISTEN:表示服务器端的某个SOCKET处于监听状态,可以接受连接了。

         SYN_RCVD: 这个状态表示接受到了SYN报文,在正常情况下,这个状态是服务器的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂,基本上用netstat你是很难看到这种状态 的,除非你特意写了一个A测试程序,故意将三次TCP握手过程中最后一个ACK报文不予发送。因此这种状态时,当收到客户端的ACK报文后,它会进入到ESTABLISHED状态。

         SYN_SENT: 这个状态与SYN_RCVD遥想呼应,当客户端 SOCKET执行CONNECT连接时,它首先发送SYN报文,因此也随即它会进入到了SYN_SENT状态,并等待服务器的发送三次握手中的第2个报文。SYN_SENT状态表示A已发送SYN报文。

         ESTABLISHED:表示连接已经建立了。

TCP 为什么是三次握手,而不是两次或四次?

TCP是一种可靠传输控制协议,核心思想是既要保证数据可靠传输,又要提高传输的效率,用三次恰恰正好可以满足以上两方面的需求,两次不靠谱,四次多余,

不用两次根本原因是无法确定客户端的接收能力,防止失效的连接请求报文段被服务端接收,从而产生错误。

失效的连接请求:若客户端向服务端发送的连接请求丢失,客户端等待应答超时后就会再次发送连接请求,此时,上一个连接请求就是『失效的』。

若建立连接只需两次握手,客户端并没有太大的变化,仍然需要获得服务端的应答后才进入ESTABLISHED状态,而服务端在收到连接请求后就进入ESTABLISHED状态。此时如果网络拥塞,客户端发送的连接请求迟迟到不了服务端,客户端便超时重发请求,如果服务端正确接收并确认应答,双方便开始通信,通信结束后释放连接。此时,如果那个失效的连接请求抵达了服务端,由于只有两次握手,服务端收到请求就会进入ESTABLISHED状态,等待发送数据或主动发送数据。但此时的客户端早已进入CLOSED状态,服务端将会一直等待下去,这样浪费服务端连接资源。

三次握手过程中可以携带数据么?

三次握手中是可以携带数据的,但是不能在第一次和第二次握手中携带,第三次握手中可以携带数据。

首先,如果第一次握手可以携带数据,要是有人恶意攻击服务器,他每次都在第一次握手中的SYN报文中放入大量的数据,因为攻击者根本就不理服务器的接收发送功能是否正常,然后疯狂重复发送SYN报文的话,服务器就会花费很长时间、内存空间来接收这些报文。

所以第一次是不可以放数据的,说简单点就是第一次握手会让服务器更容易受到攻击。而第三次的话,此时的客户端已经处于ECTABLISHED状态,对于客户端来说,他已经建立起了连接,并且也已经知道服务器的接收、发送功能是正常的了,所以ACK包就能携带数据也是可行的。

二、TCP四次挥手释放连接

TCP连接的释放一共需要四步,因此称为『四次挥手』。

TCP连接是双向的,因此在四次挥手中,前两次挥手用于断开一个方向的连接,后两次挥手用于断开另一方向的连接。

第一次挥手

若客户端A认为数据发送完成,则它需要向服务端B发送连接释放请求。该请求只有报文头,头中携带的主要参数为:

FIN=1,seq=u。此时,客户端A将进入FIN-WAIT-1状态。

1:FIN=1表示该报文段是一个连接释放请求。

2:seq=u,u-1是A向B发送的最后一个字节的序号。

第二次挥手

服务器B收到连接释放请求后,会通知相应的应用程序,告诉它客户端A向服务器B这个方向的连接已经释放。此时服务器B进入CLOSE-WAIT状态,并向客户端A发送连接释放的应答,其报文头包含:

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

1:ACK=1:除TCP连接请求报文段以外,TCP通信过程中所有数据报的ACK都为1,表示应答。

2:seq=v,v-1是B向A发送的最后一个字节的序号。

3:ack=u+1表示希望收到从第u+1个字节开始的报文段,并且已经成功接收了前u个字节。 客户端A收到该应答,进入FIN-WAIT-2状态,等待服务器B发送连接释放请求。第二次挥手完成后,客户端A到服务器B方向的连接已经释放,服务器B不会再接收数据,客户端A也不会再发送数据。但服务器B到客户端A方向的连接仍然存在,服务器B可以继续向客户端A发送数据。

第三次挥手

当服务器B向客户端A发完所有数据后,向客户端A发送连接释放请求,请求头:FIN=1,ACK=1,seq=w,ack=u+1。服务器B便进入LAST-ACK状态。

第四次挥手

客户端A收到释放请求后,向服务器B发送确认应答,请求头:ACK=1,seq=u+1,ack=w+1。此时客户端A进入TIME-WAIT状态。该状态会持续2MSL时间,若该时间段内没有服务器B的重发请求的话,就进入CLOSED状态,撤销TCB。当服务器B收到确认应答后,也便进入CLOSED状态,撤销TCB。

状态详解:

       FIN_WAIT_1: FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报文。而这两种状态的区别 是:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即 进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,当然在实际的正常情况下,无论对方何种情况下,都应该马上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可以用netstat看到。

      FIN_WAIT_2:实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你,稍后再关闭连接。

     TIME_WAIT:表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。

      CLOSING: 这种状态比较特殊,实际情况中应该是很少见,属于一种比较罕见的例外状态。正常情况下,当你发送FIN报文后,按理来说是应该先收到(或同时收到)对方的 ACK报文,再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什 么情况下会出现此种情况呢?其实细想一下,也不难得出结论:那就是如果双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。

     LAST_ACK:它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态了。

为什么客户端A要先进入TIME-WAIT状态,等待2MSL时间后才进入CLOSED状态?

为了保证服务器B能收到客户端A的确认应答。

若客户端A发完确认应答后直接进入CLOSED状态,那么如果该应答丢失,服务器B等待超时后就会重新发送连接释放请求,但此时客户端A已经关闭了,不会作出任何响应,因此服务器B永远无法正常关闭。

为什么要进行四次挥手?

TCP握手时可以把ACK和SYN放在一个报文里发送,但关闭连接时,当收到客户端的FIN报文时,只是表示对方没有数据发送给你了,但未必你所有的数据都发送给对方了。所以先会发送一个ACK报文,待数据传输完成后再向客户端发送FIN报文。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
网络通信中,TCP协议是一种常用的可靠传输协议。而其中的三次握手四次挥手则是TCP连接建立和断开过程中必然要遵循的步骤。因此,在面试中,面试官出现关于TCP三次握手四次挥手的问题也是很常见的。 面试官可能会问及TCP协议的基本原理,以及TCP连接建立、数据传输、连接关闭等方面的内容。针对TCP三次握手四次挥手,面试官可能会问到以下问题: 1. TCP为什么要进行三次握手进行连接建立三次握手是保证连接可靠性的一种手段。它主要是防止网络中存在延迟重复数据的情况,以及确保双方都可以正常收发数据。在进行三次握手时,客户端发送一个请求包,服务端接收并回应确认包,客户端再回应确认包,这样就完成了连接建立。 2. TCP为什么要进行四次挥手关闭连接四次挥手是为了确保连接的正常关闭。在关闭连接时,双方需要先告知对方自己已经没有数据要传输,等待对方回应确认。在双方都没有数据要传输后,才会真正地关闭连接四次挥手的过程中,主要是为了避免出现数据的丢失或错误。 3. 三次握手四次挥手的流程是什么? 三次握手:客户端向服务端发送SYN报文,服务端接收后发送SYN ACK报文,客户端接收后再发送ACK报文,完成连接建立四次挥手:客户端发送FIN报文告知服务端自己已经没有数据要传输了,服务端回应ACK报文进行确认;服务端同样发送FIN报文告知客户端没有数据要传输,客户端返回ACK报文进行确认;之后等待一段时间,连接会自动关闭。 总的来说,要想在面试中应对TCP三次握手四次挥手的相关问题,需要实际理解这两个过程的原理和流程。同时,也需要知道在实际应用中,TCP协议是如何确保数据可靠性和连接可靠性的。最后,要明确无论是面试还是实际工作中,了解TCP协议和网络通信的相关知识都是非常重要的。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

y_zilong

一分钱的肯定

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值