当前位置: 首页 > 后端技术 > Java

关于TCP连接的一些面试题

时间:2023-04-02 10:14:06 Java

1、为什么会有三次握手?而不是两个?有三个原因:1)第一个也是主要原因:防止旧的重复连接建立造成混淆。在网络拥塞的情况下,客户端可能会发送多个连接请求,旧的连接请求可能最先到达服务器。此时如果有两次握手,则服务器返回ACK消息建立连接,等待新的连接请求。到达后,此时旧连接已经建立,所以会造成混乱;三次握手可以避免这种情况,当服务器返回ACK报文时,客户端发现ACKnum不符合预期,就会发送一个RST(Reset)报文,指示服务器重新建立连接,服务器返回LISTEN状态;接收方在收到RST报文时会采取以下三种措施:接收方处于异步状态(SYN_SENT,SYN-RECEIVED),然后返回到LISTEN状态;接收方处于同步状态(ESTABLISHED、FIN-WAIT-1、FIN-WAIT-2、CLOSE-WAIT、CLOSING、LAST-ACK、TIME-WAIT),然后终止连接,回到CLOSED状态;2)为了保证双方都有接收和发送能力:如果只有两次握手,服务器不知道自己的发送能力和客户端的接收能力是否正常;如果握手3次,客户端返回确认报文,服务器收到报文后可以自己确认3)防止无效的连接请求到达服务器造成连接资源浪费:当客户端发送SYN报文时被阻塞,客户端重新发送SYN报文,成功与服务器建立连接,传输数据后关闭连接。之后,无效的SYN消息到达服务器。如果是双向握手,又会重新建立连接,服务器会一直等待客户端发送数据,造成资源浪费。2、为什么建立连接时握手3次,关闭连接时握手4次?由于在建立连接时服务器发送的消息中设置了SYN和ACK这两个控制位,减少了消息的发送;当连接关闭时,主动关闭方发送一条控制位FIN置1的消息,表示数据已经发送完毕,可以关闭连接,但此时接收方可能还在发送数据,而数据传输通道不能立即关闭,所以不能同时发送FIN包和ACK包。接收方先发送ACK包确认,然后等待应用程序发送数据已经发送的通知,然后发送FIN包。3、为什么TIME_WAIT状态需要经过2MSL才能回到CLOSED状态?MSL(maximumsegmentlifetime):TCP定义MSL为120s,并允许修改该值;两个原因:1)确保客户端发送的最后一个ACK包能够到达服务器。当这个包丢失时,服务器会再次发送FIN包,所以2MSL=ACK包到达服务器+服务器重新发送FIN包,然后客户端发送一个ACK包并重启2MSL定时器;2)确保所有在这个连接中产生的数据包在连接关闭之前从网络中消失,以防止与新的连接混淆。4、为什么FIN和SYN要额外消耗一个序列号?因为FIN包和SYN包都需要确认,所以如果sequencenumber没有被占用,就无法区分ACK包确认的是哪个报文。5、如果双方同时发送建立TCP连接的请求会怎样?TCPATCPB1.关闭关闭2.SYN-SENT-->...3.SYN-RECEIVED<--<--SYN-SENT4....-->SYN-RECEIVED5.SYN-RECEIVED-->...6.ESTABLISHED<--<--SYN-RECEIVED7....-->ESTABLISHEDSimultaneousConnectionSynchronization先解释一下图中符号的含义:左箭头(<--):B发送给A的TCP报文段,或者A收到B的报文;ellipsis(...):TCP段仍然滞留在网络中(延迟);丢失(XXX):TCP段丢失或被拒绝;评论将放在括号中;TCP状态表示中间报文段发送或到达后(AFTER)的状态;先说结论:双方同时发送建立TCP连接的请求,最终只会建立一个TCP连接然后我们逐行分析这个连接过程中发生了什么:双方都处于CLOSED状态;此时A发送SYN报文请求建立TCP连接;当A发送的连接消息还没有到达B时,B也发送消息A消息请求建立连接,A收到后进入SYN-RECEIVED状态;A发送的连接报文到达B,B也进入SYN-RECEIVED状态;A发送SYN+ACK报文,表示请求建立连接,确认B发送的响应注意这里的序号SEQ是初始序号,所以和第一次发送的序号一致;B也同时发送SYN+ACK报文,A收到后进入ESTABLISHED状态,表示连接建立成功;最后A发送的SYN+ACK报文到达B,我们注意到第7行B收到的报文和第5行A发送的报文不一样,为什么?这是因为B已经收到了A发送的SEQ=100的报文(见第4行),所以实际上B只收到了A发送的从序号101开始的ACK报文,也就是第7行和第5行的消息不同。B收到报文后也进入ESTABLISHED状态,最后只建立TCP连接。5.SYN-RECEIVED-->...7....-->ESTABLISHED6.当建立一个TCP连接时,一个旧的SYN报文到达服务器,会发生什么?TCPATCPB1.关闭侦听2.SYN-SENT-->...3.(重复)...-->SYN-RECEIVED4.SYN-SENT<--<--SYN-RECEIVED5.SYN-SENT-->-->LISTEN6....-->SYN-RECEIVED7.SYN-SENT<--<--SYN-RECEIVED8.ESTABLISHED-->-->ESTABLISHEDRecoveryfromOldDuplicateSYN当服务器B处于SYN-RECEIVED状态时,一个来自客户端A的旧SYN报文到达:服务器无法判断该报文是否旧,因此正常返回响应报文;client收到ACK报文后,发现ACKnum(响应号)不正确,于是返回RST报文表示reset;服务器收到RST报文后,返回LISTEN监听状态;7、在正常通信的TCP连接中,某一端死机,另一端继续发送数据会怎样?崩溃方的操作系统内核会向发送方发送RST重置消息,发送方收到RST消息后终止连接8.第三次握手失败怎么办?我们先看基本的三次握手过程:TCPATCPB1.CLOSEDLISTEN2.SYN-SENT-->-->SYN-RECEIVED3.ESTABLISHED<--<--SYN-RECEIVED4.ESTABLISHED-->-->ESTABLISHED5.ESTABLISHED->-->ESTABLISHEDBasic3-WayHandshakeforConnectionSynchronization上述流程第4行,A发送的响应报文丢失,现在B处于SYN-RECEIVED状态,会发生什么?当定时器超时,B还没有收到A的响应报文时,B会认为自己之前发送的SYN+ACK报文丢失了,会触发超时重传。重传次数默认5次;在收到响应之前,B会关闭连接;此时B可能处于SYN-RECEIVED状态或CLOSED状态:CLOSED状态:B向A发送复位报文,A收到后关闭连接;SYN-RECEIVED状态:如果B收到正常的响应报文(第4行),则连接建立成功;如果收到传输数据的请求(第5行),那么也可以成功建立连接,因为传输数据的报文中包含响应号;参考:RFC-793小林编码全网最深入的三向握手和四向握手讲解