面试题:TCP的三次握手、四次挥手
网络模型介绍
在计算机网络中有著名的OSI七层协议体系结构,概念清楚,理论完整,但是它既复杂又不实用。TCP/IP体系结构则不同,得到的广泛的应用。最终结合OSI和TCP/IP的优点,采用了一种只有五层协议的体系结构,本文的讲述的IP都是基于五层协议模型中的网络层。
OSI体系结构 | TCP/IP体系结构 | 五层体系结构 |
7 应用层 | 应用层 | 5 应用层 |
6 表示层 | ||
5 会话层 | ||
4 传输层 | 传输层 | 4 传输层 |
3 网络层 | 网络层 | 3 网络层 |
2 数据链路层 | 网络接口层 | 2 数据链路层 |
1 物理层 | 1 物理层 |
背景描述
我们知道网络层,可以实现两个主机之间的通信。但是这并不具体,因为,真正进行通信的实体是在主机中的进程,是一个主机中的一个进程与另外一个主机中的一个进程在交换数据。IP协议虽然能把数据报文送到目的主机,但是并没有交付给主机的具体应用进程。而端到端的通信才应该是应用进程之间的通信。
UDP,在传送数据前不需要先建立连接,远地的主机在收到UDP报文后也不需要给出任何确认。虽然UDP不提供可靠交付,但是正是因为这样,省去和很多的开销,使得它的速度比较快,比如一些对实时性要求较高的服务,就常常使用的是UDP。对应的应用层的协议主要有 DNS,TFTP,DHCP,SNMP,NFS 等。
TCP,提供面向连接的服务,在传送数据之前必须先建立连接,数据传送完成后要释放连接。因此TCP是一种可靠的的运输服务,但是正因为这样,不可避免的增加了许多的开销,比如确认,流量控制等。对应的应用层的协议主要有 SMTP,TELNET,HTTP,FTP 等。
概念:
TCP(Transmission Control Protocol 传输控制协议)。
这篇文章讲互联网协议,讲的很好:互联网协议入门(一) 点击打开链接
TCP 协议简介 点击打开链接
SYN:同步序列编号(Synchronize Sequence Numbers)。
SYN包是TCP连接的一种非常小的数据包。
ACK (Acknowledgement)即是确认字符。
一、TCP三次握手的过程如下:
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT(同步已发送状态)状态,等待服务器确认。
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV(同步收到)状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
完成三次握手,客户端与服务器开始传送数据
二、未连接队列
在三次握手协议中,服务器维护一个未连接队列,该队列为每个客户端的SYN包(syn=j)开设一个条目,该条目表明服务器已收到SYN包,并向客户发出确认,正在等待客户的确认包。这些条目所标识的连接在服务器处于SYN_RECV状态,当服务器收到客户的确认包时,删除该条目,服务器进入ESTABLISHED状态。
三、关闭TCP连接:四次挥手
- 第一次挥手:主机1(可以使客户端,也可以是服务器端),设置
Sequence Number
和Acknowledgment Number
,向主机2发送一个FIN
报文段;此时,主机1进入FIN_WAIT_1
状态;这表示主机1没有数据要发送给主机2了; - 第二次挥手:主机2收到了主机1发送的
FIN
报文段,向主机1回一个ACK
报文段,Acknowledgment Number
为Sequence Number
加1;主机1进入FIN_WAIT_2
状态;主机2告诉主机1,我“同意”你的关闭请求; - 第三次挥手:主机2向主机1发送
FIN
报文段,请求关闭连接,同时主机2进入LAST_ACK
状态; - 第四次挥手:主机1收到主机2发送的
FIN
报文段,向主机2发送ACK
报文段,然后主机1进入TIME_WAIT
状态;主机2收到主机1的ACK
报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,主机1也可以关闭连接了。
四、为什么要采用三次握手,两次不行吗?
谢希仁版《计算机网络》中的例子是这样的,“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送ack包。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。
参考文章:1、面试题:三次握手、四次握手内容整理 点击打开链接
2、tcp为什么要三次握手,而不能二次握手? 点击打开链接
3、TCP的三次握手与四次挥手(详解+动图) 点击打开链接
4、TCP四次挥手(图解)-为何要四次挥手 点击打开链接