面试:TCP三次握手与四次挥手看这一篇就够了!
TCP、UDP协议相关问题在面试的时候,几乎每三家公司就会有一家公司问到,被问到的概率还是非常大的。之前自己一点都不重视这个,觉得写代码的时候又不会用到这个,所以看的时候也只是浏览大概意思,面试官问起也是含糊其辞,面试结果可想而知。碰壁这么多次,只能含泪找资料看书详细的总结一下,废话不多说开始吧。
问题一:说说UDP协议和TCP协议的区别?
这个问题我自己在面试的时候有被问到过,虽然频率不是很高,但是当时答得效果也不是很好,所以也总结一下。
首先,TCP是面向连接而UDP是无连接的,也就是说UDP发送数据前不需要建立连接;其次,TCP提供的服务更可靠,也就是说通过TCP连接传输的数据无差错、不丢失、不重复,并且能够按序到达,而UDP则不保证可靠交付;第三,TCP是面向字节流的,也就是说TCP处理数据时,看成一连串无结构的字节流,而UDP则面向报文的,TCP连接只能是点到点的,但UDP不但支持一对一,还可以一对多、多对一和多对多的交互通信,UDP的首部开销8个字节比TCP的20字节要小(每个TCP报文段都至少有20个字节的首部开销,而UDP仅有8字节的开销);第四,TCP协议提供拥塞控制和流量控制机制; 而UDP协议不提供;第五,TCP传输效率相对较低,UDP传输效率高;第六,TCP协议对系统资源要求较多,UDP协议对系统资源要求较少。
问题二:说说TCP协议的三次握手?
这个问题不用多说,绝对的高频问题。先来一张TCP报文段结构图。
面试时直接回答:
第一次握手:客户端作为连接建立发起端,选择客户端初始***x,向服务器发送(SYN=1,seq=x)的SYN报文段,并进入SYN_SENT状态(有的书籍和文章写的是SYN_SEND状态,不过我觉得是错的,所以这里写的SYN_SENT,如果有误欢迎指正),等待服务器确认;
第二次握手:服务器收到客户端发送的SYN段后,选择服务器初始***y,向客户端发送(SYN=1,ACK=1,seq=y,ack_seq=x+1)的SYNACK报文段。同时服务器状态由LISTEN进入SYN_RCVD状态。
第三次握手:客户端收到服务器的SYNACK段后,向服务器发送(ACK=1,seq=x+1,ack_seq=y+1)的ACK报文段,同时客户端进入ESTABLISHED状态,客户端确认连接已建立;当服务器收到ACK段后,也进入ESTABLISHED状态,也确认连接已建立。至此,双方均确认连接建立成功。
拓展部分:
建立连接过程中客户端状态名称与含义如下:关闭状态 CLOSED,处于初始状态;同步已发送状态 SYN_SENT;已建立状态 ESTABLISHED,表示可以传送数据。
建立连接过程中服务器端状态名称与含义如下:关闭状态 CLOSED,处于初始状态:监听状态 LISTEN:同步收到状态 SYN_RCVD;已建立状态 ESTABLISHED,表示可以传送数据。
问题三:TCP协议的四次挥手
面试时直接回答:
第一次挥手:当客户端向服务器发送完最后一个数据段后,可以发送一个FIN报文段(FIN=1,seq=u),请求断开客户到服务器的连接,其状态由 ESTABLISHED进入FIN_WAIT_1,在这一状态下,只能接收服务器发送过来的数据,而不再发送数据。需要注意的是,FIN段不封装应用层数据,但是也要消耗掉1个***(类似于SYN段)。
第二次挥手:服务器收到客户的FIN段后,向客户发送一个ACK段(ACK=1,seq=v,ack_seq=u+1),ACK段可以封装应用层数据(如果有)。服务器状态由 ESTABLISHED进入CLOSE_WAIT,在这一状态下,服务器仍然可以发送数据,但不再接收数据。当客户收到ACK段后,其状态由 FIN_WAIT_1进入 FIN_WAIT_2,仍然可以接收来自服务器的数据。此时的TCP连接已经关闭了客户向服务器方向的数据传输,故也称为半关闭。
第三次挥手:当服务器向客户发送完最后一个数据段后,服务器向客户发送FIN段(FIN=1,ACK=1,seq=w, ack_seq=u+1),同样,该FIN段也不携带应用层数据,服务器状态则由CLOSE_WAIT进入 LAST_ACK,此时服务器也不再发送数据。
第四次挥手:当客户收到服务器发送的FIN段后,向服务器发送ACK段(ACK=1,seq=u+1,ack_seq=w+1),其状态由FIN_WAIT_2进入 TIME_WAIT,等待2MSL( Maximum Segment Lifetime)时间,然后进入 CLOSED状态,最终释放连接;服务器在收到最后一次ACK段后,状态由 LAST_ACK进入 CLOSED,最终释放连接。
拓展部分:
断开连接过程中,客户端状态名称与含义如下: ESTABLISHED状态,表示可以传送数据;FIN_WAIT_1终止等待1状态,等待服务器端的确认;FIN_WAIT_2终止等待2状态,等待服务器端发出的连接释放报文段;TIME_WAIT时间等待状态,表示等待2倍MSL时间后进入关闭状态 CLOSED。
断开连接过程中,服务器端状态名称与含义如下:ESTABLISHED状态,表示可以传送数据;CLOSE_WAIT关闭等待状态: LAST_ACK最后确认状态;CLOSED关闭状态。
问题四:为什么TCP不采用二次握手建立连接,而一定要采用三次握手建立连接呢?
因为网络存在数据丢失,第二次握手控制段可能丢失,这样主动发起连接的一方由于没有收到第二次握手控制段,则无法建立连接,而接受连接建立的一方则认位连接已建立,从而出现无效连接。另外,二次握手建立连接,也无法避免失效连接请求。还有没有第三次握手,服务器也无法确认客户是否已经清楚自己的初始状态,如果此时服务器就开始给客户发送数据,则可能出现差错。
最后:其它相关TCP、UDP面试问题遇到后再总结,毕竟总结起来确实需要花费不少时间。如有错误欢迎指正。