TCP建立连接的三次握手和四次挥手解析

首先需要知道,在TCP层,有个FLAGS字段,这个字段有以下几个标识:SYN, FIN, ACK, PSH, RST, URG.
其中,对于我们日常的分析有用的就是前面的五个字段。
它们的含义分别是:

SYN表示建立连接,

FIN表示关闭连接,

ACK表示响应,

PSH表示有DATA数据传输,

RST表示连接重置。

此外连接过程中还会产生***sequence number(顺序号码)和 acknowledge number(确认号码)

三次握手:

实际上连接建立成功代表一次握手的成功,之所以称之为三次握手是因为在建立连接的过程中客户端和服务器有三次报文的发送,称之为“三报文握手”更为确切,首先,客户端发送连接请求报文,带有建立连接标记SYN = 1,顺序号码seq = x(随机产生(详情见:https://blog.csdn.net/a19881029/article/details/38091243));服务器端收到请求后发送确认报文给客户端,带有SYN = 1,响应标记ACK = 1,seq = y (随机产生),确认号码ack = x + 1(即在客户端请求报文的顺序号码seq基础上上加一);客户端收到确认报文后告知服务器表示已收到确认报文,于是需要再次向服务器发送报文,不再带有建立连接标记,只带有响应标记ACK = 1,顺序号码seq = x + 1(即在客户端自己第一次发送报文时的顺序号码上加一),确认号码ack = y + 1(即在服务器确认报文中顺序号码seq基础上加一),ack关注于接收报文中的seq,这样通俗上讲的三次握手完成,连接建立。
图片来自百度

面试常问:

为什么需要第三次握手?
在客户端请求服务器,服务器响应客户端后,直接建立连接不就可以了吗?
为什么客户端还需要第三次向服务器发送表示已收到确认报文的报文?

参考答案:

由于网络原因,客户端的第一次请求可能滞留,客户端于是发送第二次请求,服务器收到第二次请求报文,建立连接并且使用完关闭连接后,客户端第一次滞留的请求这时又被服务器接收,若不进行第三次握手,服务器发送确认报文后直接建立连接,显然不合理,因为客户端已经通过第二次请求完成了需要的工作。

四次挥手:

同理,四次挥手也是通过发送报文来完成,首先,客户端发送关闭连接请求报文(注意连接和关闭都是客户端先主动),带有关闭连接标记FIN = 1,顺序号码seq = u(随机生成);服务器收到后发送确认报文,带有FIN = 1,响应标记ACK = 1,顺序号码seq = v(随机生成),确认号码ack = u + 1(即在客户端关闭请求报文顺序号码seq基础上加一);客户端收到后则无法在向服务器发送数据,但连接还只是客户端单向断开,服务器可能还有数据要传送到客户端,传送完之后,服务器被动关闭,再次发送断开连接报文,带有FIN = 1,ACK = 1,seq = w(随机生成),ack = u + 1(同理是在客户端关闭请求报文顺序号码seq基础上加一);客户端收到后发送确认报文,带有ACK = 1, seq = u + 1(及在客户端第一次关闭请求报文的seq基础上加一),ack = w + 1(即在服务器关闭连接请求报文的seq基础上加一),ack关注于接收报文中的seq,这样四次挥手完成,客户端等待2MSL后连接正式关闭。
图片来自百度

面试常问:

为什么客户端在四次挥手后还要等待2MSL呢?

参考答案:

由于网络原因,客户端第四次挥手请求确认服务器可能接收不到,那么服务器就会认为是第三次挥手关闭请求报文客户端没有接收到,就会再次发送关闭连接请求报文,如果此时客户端关闭了,就无法响应服务器了,连接也就没有正常关闭。