SYN(synchronous) 同时存在的,同步的, ACK(acknowledgement) 确认字符
如果是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
FIN(finish结束、断开连接) ACK(acknowledgement) 确认字符
当A端和B端要断开连接时,需要四次握手,这里称为四次挥手。
断开连接请求可以由客户端发出,也可以由服务器端发出,在这里我们称A端向B端请求断开连接。
四次挥手中客户端收到服务器的FIN后,处于TIME_WAIT状态,也叫2MSL状态 在这个状态等候2MSL时间有什么用处呢,为什么要等待2MSL时间?
存在这种情况,如果客户端收到服务器的FIN以后,发送FIN的ACK给服务器,但是服务器没有收到
这个ACK,服务器会超时发送FIN,如果客户端不等待一段时间,将收不到重发的FIN,就不会重发
ACK,这样就不能正确的关闭连接,那等待多久比较合适呢?首先服务器有一个超时时间,如果在这个
超时时间内,收到了客户端的ACK,就可以正常关闭,如果收不到,就会重传FIN,所以这两段时间加起来就是
服务器的timeout+FIN的传输时间,为了保守起见,采用更加保守的等待时间2MSL,如果2MSL时间内没有收到
服务器的FIN,那就说明服务器端正确收到ACK了,如果收到了服务器的FIN呢,就客户端就重新发送ACK,这时候
客户端又会等待2MSL时间。
关闭一个TCP连接后,过段时间后用相同的地址和IP建立另一个连接,新连接称为老连接的
化身,因为他们的IP地址和端口号都相同,TCP必须防止来自前一个连接的老的重复分组在该连接终止后再出现。
从而被新连接的报文,为了因对这个问题,TCP不允许处于TIME_WAIT的状态的连接发起
新的化身。即不允许再使用处于TIME_WAIT阶段的连接的IP 端口号进行连接,既然TIME_WAIT状态的持续时间为2MSL
就可以保证让某个方向的分组最多存活MSL秒就被丢弃,另一个方向的应答报文最多存活MSL秒就被丢弃,
通过实施这个规则,我们就能保证每成功建立每个TCP连接时,来自老连接老的重复分组都已经在网络中消逝了
四次挥手是TCP的半关闭造成的,所谓的半关闭就是TCP提供了连接的一端在结束他的发送后还能接受另一端数据的能力
TCP连接时全双工的,所以需要每个方向单独进行关闭,那么能将四次挥手中的第二步和第三步进行合并?这就变成了“三次挥手”了?
原因是有可能客户端可以发送ACK的时候还需要发送数据给客户端,所以不能同时发送ACK和FIN,只能先将ACK发送到客户端,等服务端发送完数据以后,再发送FIN到到客户端