三次握手和四次挥手
TCP通过三次握手建立连接,四次挥手断开连接,流程图如下
1.三次握手
- 客户端发送给服务器SYN包到服务器,其中包含初始化序列号seq,假设seq=a,此时客户端进入SYN_SENT状态。
- 服务器收到了客户端发过来的SYN包,如果同意建立连接,发送给客户端一个ACK+SYN包,包含初始化序列号seq,假设为b,还包含一个ack,即为对客户端序列号的确认号,
此处为a+1,此时服务器进入SYN_RECV状态 - 客户端收到了服务器端发过来的ACK+SYN包,发给服务器一个ACK包,包含初始化序列号以及对服务器的序列号确认号即为ack=b+1,此时连接建立完成,客户端和服务器端
进入ESTAB_LISHED状态,彼此之间可以发送数据包了。
### 为什么需要三次,不是两次?不是四次五次???
客户端发送给服务器端的报文段没有收到确认,客户端又重传了一次连接请求,这次成功了,现在的情况就是第一个报文段丢了没到服务器,第二个到了,建立了连接。
假设第一个报文段不是丢了,而是由于某种原因在网络中延误了,如果是两次握手建立连接的话,第二个到达的报文段也会建立连接,其实这个报文段已经被认为失效了,
服务器却以为建立了连接,等待发来请求,许多资源就这么浪费了,如果是三次的话,客户端并不会对第二个连接请求进行确认,连接也不会建立。2.四次挥手
- 客户端发送给服务器FIN包,seq=a
- 服务器端发送给客户端ACK包,ack=a+1,seq=b,进入CLOSED_WAIT状态
- 服务器端发送FIN给客户端
- 客户端发送给服务器端ACK包,之后进入TIME_WAIT状态,等待2MSL时间后,连接断开
### 为什么TIME_WAIT要等待2MSL
MSL即Maximum Segment Lifetime,就是最大报文生存时间,是任何报文在网络上的存在的最长时间,超过这个时间报文将被丢弃。《TCP/IP详解》中是这样描述的:
MSL是任何报文段被丢弃前在网络内的最长时间。RFC 793中规定MSL为2分钟,实际应用中常用的是30秒、1分钟、2分钟等。
两个原因1.确保ACK报文能到达服务器,2.让旧的报文在网络中消失,防止下一个连接出现上一个连接的报文