TCP三次握手
TCP
建立连接的过程中需要发送三次报文,所以TCP
建立连接也被称为三次握手,假设客户端向服务器发起TCP
连接:
- 第一步握手:客户端的
TCP
程序首先向服务器的TCP
程序发送一个TCP
报文。这个报文不包含数据,且它的SYN
标志位被置为1
,表示这是一条建立连接的TCP
报文段,因此这个报文段也被称为SYN报文段。客户端的TCP
程序随机选择一个序号作为客户端报文的初始序号(假设序号为client_isn
),放入这个报文段的序号部分。这个报文段由运输层传递到网络层后,被封装在一个IP
数据报中发往服务器; - 第二步握手:包含
SYN
报文段的IP
数据报被服务器接收,服务器的网络层将SYN
数据报抽取出来,交给运输层,同时服务器为该TCP
连接分配资源(包括发送缓存、接收缓存和变量等),并向客户发送允许连接的TCP
报文段。这条允许连接的报文段不包含数据,SYN
标志位也被置为1
,同时它的ACK
标志位也被置为1,表示它是SYN
报文段的确认报文,所以这条允许连接的报文段也被称为SYNACK报文段。服务器随机选择一个序号,作为服务器报文段的初始序号(假设称为server_isn
),并将其放入SYNACK
报文段的序号部分,同时确认号字段被设置为client_isn + 1
(SYN
报文段的序号+1)。这个报文段可以解释为服务器向客户端说:“我收到了你的连接请求,我允许你连接,我的初始序号是server_isn
”。 - 第三步握手:当客户端接收到
SYNACK
报文段后,它也将为TCP
连接分配资源(缓存和变量),同时生成一条SYNACK
报文段的确认报文,并发送给服务器。由于经过上面两个步骤,已经算是建立了连接,所以这次的SYN
标志位将被置为0
,而不是1
(ACK
标志位是1
)。同时,这条报文段的序号被设置为client_isn + 1
(第一条客户报文的序号是client_isn
,而这是它的下一条,所以+1
),而确认序号被设置为server_isn + 1
(第一条服务器报文的序号server_isn
,客户端成功接收,所以期望服务器下一次发送server_isn + 1
)。和上面两条报文不同,第三条报文可以携带数据,比如HTTP
的请求就是在TCP
的第三次握手报文中发送到服务器的。
TCP四次断开
TCP
在断开连接时,客户端与服务器之间要交换四次报文,所以,TCP
的断开连接也叫四次断开。
- 第一步断开:客户端进程发出断开连接指令,这将导致客户端的
TCP
程序创建一个特殊的TCP
报文段,发送到服务器。这个报文段的FIN
字段被置为1,表示这是一条断开连接的报文; - 第二步断开:服务器接收到客户端发来的断开连接报文,向客户端回送这个报文的确认报文(
ACK
字段为1
),告诉服务器已经接收到FIN
报文,并允许断开连接; - 第三步断开:服务器发送完确认报文后,服务器的
TCP
程序创建一条自己的断开连接报文,此报文的FIN
字段被置为1
,然后发往客户端; - 第四步断开:客户端接收到服务器发来的
FIN
报文段,则产生一条确认报文(ACK
为1
),发送给服务器,告知服务器已经接收到了它的断开报文。服务器接收到这条ACK
报文段后,释放TCP
连接相关的资源(缓存和变量),而客户端等待一段时间后(半分钟、一分钟或两分钟),也释放处于客户端的缓存和变量;