TCP/IP的三次握手和四次挥手
文章目录
1.三次握手示意图
SYN(synchronous) 同时存在的,同步的, ACK(acknowledgement) 确认字符
-
第一次握手
当客户端向服务器发起连接请求时,客户端会发送同步序列标号SYN到服务器,在这里我们设SYN为m,等待服务器确认,这时客户端的状态为SYN_SENT。 -
第二次握手
当服务器收到客户端发送的SYN后,服务器要做的是确认客户端发送过来的SYN,在这里服务器发送确认包ACK,这里的ACK为m+1,意思是说“我收到了你发送的SYN了”,同时,服务器也会向客户端发送一个SYN包,这里我们设SYN为n。这时服务器的状态为SYN_RECV。
一句话,服务器端发送SYN和ACK两个包。 -
第三次握手
客户端收到服务器发送的SYN和ACK包后,需向服务器发送确认包ACK,“我也收到你发送的SYN了,我这就给你发个确认过去,然后我们即能合体了”,这里的ACK为n+1,发送完毕后,客户端和服务器的状态为ESTABLISH,即TCP连接成功。
在三次握手中,客户端和服务器端都发送两个包SYN和ACK,只不过服务器端的两个包是一次性发过来的,客户端的两个包是分两次发送的。
2.TCP 为什么是三次握手,为什么不是两次或四次?
如果是2次握手,那么只要server发出确认,新的连接就建立了。但是这样会遇到一个新的问题?
(1)如果client发送给server的请求是过期的请求,那当server接收到的请求的时候,可能client就不想建立连接了,此时如果只有server确认就能建立连接,显示不行。
(2)如果server在接收到的请求后,发送之后理论上就建立连接了,但是server发送确认信息,client也不一定能接收到,server不能知道是否client接收到自己的确认信息。
第一个包,即A发送B的SYN包中途被丢,没有到达B
—> A会周期性超时重传,直到收到B的确认
2.第二个包,即B发给A的SYN和ACK中途被丢,没有到达A
----> B会周期性超时重传,直到收到A的确认
3.第三个包,即A发给B的ACK中途被丢,没有到达B
–>此时A发送完ACK,单方面认为TCP已经建立了,但是B没有认为连接建立了。
①:如果此时没有数据发送,B会周期性重传SYN和ACK,直到收到A的ACK为止
②:A发送完ACK,单方面认为连接已经建立,假定A有数据发送,B收到A的DATA+ACK。自然就可以建立连接了,也就可以接受DATA了
③:B如果有数据发送,数据发送不了,所以也会超时重传SYN和ACK
3.四次挥手
FIN(finish结束、断开连接) ACK(acknowledgement) 确认字符
当A端和B端要断开连接时,需要四次握手,这里称为四次挥手。
断开连接请求可以由客户端发出,也可以由服务器端发出,在这里我们称A端向B端请求断开连接。
-
第一次挥手
A端向B端请求断开连接时会向B端发送一个带有FIN标记的报文段,这里的FIN是FINish的意思。 -
第二次挥手
B端收到A发送的FIN后,B段现在可能现在还有数据没有传完,所以B端并不会马上向A端发送FIN,而是先发送一个确认序号ACK,意思是说“你发的断开连接请求我收到了,但是我现在还有数据没有发完,请稍等一下呗”。 -
第三次挥手
当B端的事情忙完了,那么此时B端就可以断开连接了,此时B端向A端发送FIN序号,意思是这次可以断开连接了。 -
第四次挥手
A端收到B端发送的FIN后,会向B端发送确认ACK,然后经过两个MSL时长后断开连接。
MSL是Maximum Segment Lifetime,最大报文段生存时间,2个MSL是报文段发送和接收的最长时间。
4.问题:2MSL状态什么意思?
四次挥手中客户端收到服务器的FIN后,处于TIME_WAIT状态,也叫2MSL状态 在这个状态等候2MSL时间有什么用处呢,为什么要等待2MSL时间?
1:可靠的实现TCP全双工连接的终止
存在这种情况,如果客户端收到服务器的FIN以后,发送FIN的ACK给服务器,但是服务器没有收到
这个ACK,服务器会超时发送FIN,如果客户端不等待一段时间,将收不到重发的FIN,就不会重发
ACK,这样就不能正确的关闭连接,那等待多久比较合适呢?首先服务器有一个超时时间,如果在这个
超时时间内,收到了客户端的ACK,就可以正常关闭,如果收不到,就会重传FIN,所以这两段时间加起来就是
服务器的timeout+FIN的传输时间,为了保守起见,采用更加保守的等待时间2MSL,如果2MSL时间内没有收到
服务器的FIN,那就说明服务器端正确收到ACK了,如果收到了服务器的FIN呢,就客户端就重新发送ACK,这时候
客户端又会等待2MSL时间。
2: 允许老的重复字节在网络中消逝。
关闭一个TCP连接后,过段时间后用相同的地址和IP建立另一个连接,新连接称为老连接的
化身,因为他们的IP地址和端口号都相同,TCP必须防止来自前一个连接的老的重复分组在该连接终止后再出现。
从而被新连接的报文,为了因对这个问题,TCP不允许处于TIME_WAIT的状态的连接发起
新的化身。即不允许再使用处于TIME_WAIT阶段的连接的IP 端口号进行连接,既然TIME_WAIT状态的持续时间为2MSL
就可以保证让某个方向的分组最多存活MSL秒就被丢弃,另一个方向的应答报文最多存活MSL秒就被丢弃,
通过实施这个规则,我们就能保证每成功建立每个TCP连接时,来自老连接老的重复分组都已经在网络中消逝了
5.为什么关闭连接需要四次挥手?
四次挥手是TCP的半关闭造成的,所谓的半关闭就是TCP提供了连接的一端在结束他的发送后还能接受另一端数据的能力
TCP连接时全双工的,所以需要每个方向单独进行关闭,那么能将四次挥手中的第二步和第三步进行合并?这就变成了“三次挥手”了?
原因是有可能客户端可以发送ACK的时候还需要发送数据给客户端,所以不能同时发送ACK和FIN,只能先将ACK发送到客户端,等服务端发送完数据以后,再发送FIN到到客户端