TCP三次握手有很多文章来讲述,不过我总觉得有点抽象,这次打算通过一个“打印机”的小故事来讲解三次握手和四次挥手.
TCP提供面向连接的服务,在传送数据前必须建立连接,TCP连接是通过三次握手建立的。

三次握手过程:

有一次工作,小赵希望用打印机打点材料,可是自己电脑没驱动,就想着喊小王帮忙打一下.
1.是防止服务端开启无用的连接增加服务器的开销
2.防止已失效的连接请求报文段突然又到了服务端,引发错误.
由于网络传输是存在网络阻塞的可能行,如果在服务端发送了SYN报文之后,没有第三次握手,服务端不知道这个报文是否客户端能接收到.这种情况下,服务端就会认为当前端口可用,端口就一直开着,等到客户端因超时重新发出请求时,服务器就会重新开启一个端口连接。这样一来,就会有很多无效的连接端口白白地开着,导致资源的浪费。

简单来说,就是小王听到小赵喊话之后,回复“小赵,我是小王,我在”.然后小赵就不回任何消息了.小王不知道小赵听没听到回复的消息,也不知道小赵之后要干什么,所以只能一直等待,这样就造成小王其他的事情也干不了.
还有一种情况是已经失效的客户端发出的请求信息,由于某种原因传输到了服务器端,服务器端以为是客户端发出的有效请求,接收后产生错误。

所以我们需要“第三次握手”来确认这个过程:
通过第三次握手的数据告诉服务端,客户端有没有收到服务器“第二次握手”时传过去的数据,以及这个连接的序号是不是有效的。若发送的这个数据是“收到且没有问题”的信息,接收后服务器就正常建立 TCP 连接,否则建立 TCP 连接失败,服务器关闭连接端口。由此减少服务器开销和接收到失效请求发生的错误。
简单说,就是三次挥手已经足够创建可靠的连接,没有必要再多一次握手导致花费更多的时间建立连接
服务端不会进行任何的动作,而客户端由于一段时间内没有收到服务端发来的确认报文,等待一段时间后会重新发送SYN报文,如果仍然没有回应,会重复这个过程,直到发送次数超过最大重传次数限制,就会返回连接建立失败。
客户端会继续重传,直到次数限制;而服务端此时会阻塞在accept()处,等待客户端发送ACK报文
服务端同样会采用类似客户端的超时重传机制,如果重试次数超过限制,则accept()调用返回-1,服务端建立连接失败;
而此时客户端认为自己已经建立连接成功,因此开始向服务端发送数据,但是服务端的accept()系统调用已经返回,此时不在监听状态,因此服务端接收到客户端发送来的数据时会发送RST报文给客户端,消除客户端单方面建立连接的状态。
四次挥手过程:

四次挥手过程:
上回说到小赵让小王帮忙打印材料,可是材料总有打完的时候.此时小赵发现需要打印的材料都已经发送给小王了,就准备告诉小王差不多可以结束了

通过“打印机小故事”明显看出来,服务端在收到客户端断开连接FIN报文后,并不会立即关闭连接,而是先发送一个ACK包先告诉客户端收到关闭连接的请求,只有当服务器的所有报文发送完毕之后,才发送FIN报文断开连接,因此需要四次挥手.
为了保证客户端发送的最后一个 ACK 报文段能够到达服务端。网络存在丢包问题,怕最后一次客户端发送的ACK报文丢失,导致服务端因没有收到报文一直处在LAST_ACK状态中,无法关闭.如果在一段时间服务端没有收到报文,会重发FIN报文,此时客户端收到报文之后,会重新发送ACK报文,并将等待时间重置为2MSL.直到最后客户端和服务端都进入CLOSED状态
防止已失效的连接请求报文段出现在本连接中.经过2MSL时间,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失.这样就可以使下一个连接中不会出现这种旧的连接请求报文段。
MSL( Maximum Segment Lifetime),最大报文生存时间.它是任何报⽂在⽹络上存在的最⻓时间,超过这个时间报⽂将被丢弃。
至于为什么是2倍,是考虑存在双方发送的情况.客户端端先发送一个报文,在一个MSL后到达服务端,然后服务端作出响应,经过一个MLS到达客户端.一去一回正好2MSL

一个完整的三次握手四次挥手如下图所示:
