2.6 TCP连接的建立和终止
2.6.1 三路握手
![](https://i-blog.csdnimg.cn/blog_migrate/92722bacf42c26de365744440f1dfda9.png)
(1)连接前准备:服务端通过调用socket、bind、listen准备好接受外来的连接。
通常,我们会在listen之后立刻调用accept,accept会从已完成三路握手的队列中取走一个。如果当前没有可取的,则进入阻塞状态,直到有三路握手完成,则取出,程序继续向下执行。
所以,我们常常在三路握手之前调用accept,accept并不参与三次握手过程,而是进入阻塞状态,等到三路握手完成,accept返回。
(2)第一次握手:客户端调用connect,使客户端先向服务器发送一个SYN(同步)分节,
告诉服务器自己将在待建立的连接中发送的数据的初始序列号。
(3)第二次握手:服务器收到SYN后,发送一个包含SYN和ACK的分节分节给客户。
(4)第三次握手:客户端收到服务器的SYN后向服务器返回一个ACK。connect返回,三次握手完成。
2.6.3 TCP连接终止
![](https://i-blog.csdnimg.cn/blog_migrate/82390e5ed50e2992c377a200be2d16da.png)
(1)第一次挥手:客户端调用close,使其发送一个FIN分节给服务端。
(2)第二次挥手:服务端收到FIN后返回一个ACK。
(3)第三次挥手:一段时间后服务端也调用close发送一个FIN给客户端
(4)第四次挥手:客户端收到FIN后返回ACK,并进入TIME_WAIT状态,等待2MSL时间,关闭连接。
服务端则在收到客户端的ACK后关闭连接。
注意:第一个发出FIN的不一定是客户端,比如在HTTP1.0中是由服务器主动关闭连接。
2.7 关于TIME_WAIT状态
MSL(max segment lifetime)最长分节生命期
TIME_WAIT存在的意义:
(1)如果最终的ACK丢失,服务端会重新发送FIN给客户端,客户端必须等待2MSL时间,防止因为最终的ACK丢失导致服务端的连接无法关闭。
(2)等待2MSL时间后该IP地址+端口号组合才可以给其他应用进程使用,使网络中残留的老的重复的分节在网络中消逝,防止其被之后使用这个连接的应用进程接收。