Home
TCP的三次握手
1.第一次握手:建立连接。客户端发送连接请求报文段,将SYN位置为1,Seq为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;
2.第二次握手:服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Ack为x+1(seq+1);同时,自己自己还要发送SYN请求信息,将SYN位置为1,Seq为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;
3.第三次握手:客户端收到服务器的SYN+ACK报文段。然后将Ack设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。
为什么要三次握手?
答:三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收机能正常。
第一次握手:
Client什么都不能确认;Server确认了对方发送正常和自己的接受正常。
第二次握手:
Client确认了:自己发送、接收正常,对方发送、接收正常;Server确认了:自己接收正常,对方发送正常,不能确定自己的发送正常。
第三次握手:
Client确认了:自己发送、接收正常,对方发送、接收正常;Server确认了:自己发送、接收正常,对方发送接收正常所以三次握手就能确认双发收发功能都正常,缺一不可。
- 现假定出现一种异常情况,即A发出的第一个连接请求报文段并没有消丢失,而是在某些网络节点长时间滞留了,以至延误到连接释放以后的某个时间点才到达B。本来这就是一个早已失效的报文段。但B收到此失效的连接请求报文段后,误认为A又重新发起了一次连接请求。于是就向A发送确认报文段,同意建立连接。假定不采用三次握手,那么只要B发出确认报文,新的连接就建立了。
- 由于现在A并没有发出建立连接请求因此不会理B的确认,也不会向B发送数据。但B认为新的运输连接已经建立了,并一直等待A发来数据,B中的资源就这样白白浪费了。
- 采用三次握手可以预防上面现象的发生。例如:就在上面例子中,A不会向B发送确认请求,B自然不会建立连接。
四次挥手
(1)第一次挥手: Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
(2)第二次挥手: 此时服务器端可能还要给客户端传送数据,不能急着关闭。Server收到FIN后,发送一个ACK给Client,确认序号为收到序号seq+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
(3)第三次挥手: 服务器端数据传送完成之后,Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
(4)第四次挥手: Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
为什么四次挥手?
答:根本原因是,一方发送FIN只表示自己发完了所有要发的数据,但还允许对方继续把没发完的数据发过来。 举个例子:A和B打电话,通话即将结束后,A说“我没啥要说的了”,B回答“我知道了”,但是B可能还会有要说的话,A不能要求B跟着自己的节奏结束通话,于是B可能又巴拉巴拉说了一通,最后B说“我说完了”,A回答“知道了”,这样通话才算结束。
四次挥手中TIME_WAIT作用
为什么A在TIME-WAIT状态必须等待2MSL的时间呢?
为了保证A发送的最后一个ACK报文段能够到达B。这个ACK报文段有可能丢失,因而使处在LSAT-ACK状态的B收到不到对方发送的FIN+ACK报文段的确认。B会超时重传这个FIN+ACK报文段。而A就能在2MSK时间内收到恶搞重传的FIN+ACK报文段。接着A重传一次确认,重新启动2MSL计时器,最后,A、B都能正常进入close状态。
- 如果A在TIME-WAIT状态不等待一段时间而是在发送完ACK报文段以后立即释放连接,那么无法收到B重传的FIN+ACK报文段,因而也不会发送一次确认报文段,这样,B就无法正常进入close状态。