当网络通信采用TCP协议时,在真正的数据传输开始之前,server和client之间必须建立一个连接,当数据传输完成,双方不再需要这个连接时可以释放这个连接。连接的建立是需要三次握手的,连接的释放则需要四次握手,每个连接的建立都是需要资源消耗和时间消耗的。
一、三次握手
三次握手的过程?
客户端主动打开连接,服务器端被动打开连接。
1)client端发送连接请求报文,SYN=1,sep=x,然后client进入SYN-SENT状态,等待server确认。
2)server端初始处于LISTEN状态,收到连接请求后,由SYN字段得知client要请求连接,则回复一个报文,ACK=1, SYN=1, ack=x+1, seq=y,然后进入SYN-RCVD状态,此时操作系统为该TCP连接分配TCP缓存和变量。
3)client端收到server端的确认报文后,检查ack是否为x+1,ACK是否为1,如果正确则将标志位ACK=1,ack=y+1,seq=x+1,并且此时操作系统为该TCP连接分配TCP缓存和变量,向server发送一个确认报文。(此时client端进入ESTABLISHED状态)
4)server端在收到确认报文后,检查ACK是否为1,ack是否为y+1,如果正确则连接建立成功,client和server进入ESTABLISHED状态,完成三次握手。随后client和server开始传输数据。
为什么需要三次握手?二次握手是不是也可以?
为了防止已失效的连接请求报文再次传输到服务端,从而产生错误请求。比如:客户端C发出连接请求,但因连接请求报文丢失而未收到确认,于是C再重传一次连接请求,后来收到了确认,建立了连接。数据传输完毕之后,就释放了连接。C发出了两个连接请求,其中一个丢失了,但丢失的报文可能是在网络中滞留了,延误到连接释放后的某个时间才到达服务器S,此时S误认为这个是客户C发出的连接请求,于是就向C发出了确认报文,同意建立连接,从而进入ESTABLISHED状态。如果不采用三次握手,只要B发出确认后,就建立新的连接了,此时C不理睬B的确认且不发送数据,则B一直等待C发送数据,浪费资源。
server端容易受到SYN攻击?
服务端的资源是在二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易受到SYN洪泛攻击。SYN攻击就是client在短时间内伪造大量不存在的ip地址,并向server不断地发送SYN包,server则回复确认包,并等待client确认,由于源地址不存在,因此server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。
防范SYN攻击的措施?
降低主机的等待时间从而使主机尽快释放半连接占用;若短时间收到某ip的重复SYN则丢弃后续请求。
二、四次挥手
一方主动断开连接,另一方被动断开连接
四次挥手过程?
通信双方分别记做A和B
1)A没有要传输给B的数据了,因此A主动发起释放连接请求的报文,置FIN=1,seq=x。然后A进入FIN-WAIT(终止等待)状态,等待B的确认。
2)B收到请求报文,根据FIN=1了解到A希望释放连接,但是此时B尚有数据需要传输给A,因此B立即发出确认回复报文,设置ACK=1,ack=x+1,seq=y。接下来B进入CLOSE-WAIT(关闭等待)状态。
3)A收到B的确认报文后,继续等待B的释放连接请求报文。依然处于FIN-WAIT状态。
4)B的数据已经全部传输完毕,没有要向A传递的数据,可以释放连接了。因此,B发送释放连接报文,设置FIN=1,ACK=1,ack=x+1,seq=u,并开启超时重传的倒计时。进入LAST-ACK(最后确认)状态。等待A的确认。
5)A收到B的报文,通过FIN=1得知B要释放连接,因此发送确认回复报文,设置ACK=1,ack=u+1,seq=x+1。A进入TIME-WAIT(时间等待)状态,此时,TCP未释放,需要经过时间等待计时器设置的时间2MSL后,A才进入CLOSE状态。
6)B收到A发来的确认回复报文后,进入CLOSE状态,释放连接。
为什么连接的时候是三次握手,关闭的时候却需要四次挥手?
由于连接建立前尚未有数据传输,server端收到client的SYN报文后,可以直接发送SYN+ACK报文,其中ACK是用来应答的,SYN是用来同步的。但是在关闭连接时,当被动关闭的一方收到FIN报文时,很可能尚有数据未传输完成,不能立即释放连接。因此,只能先回复一个ACK报文,告诉发起释放连接的一端:我收到了你发的FIN报文。等数据传输完成后,再发送一个FIN报文,告诉我已经没有数据传输了,可以释放连接了。
最后一次挥手时为什么要等待2MSL的时间?
1)为了保证A发送的最后一个ACK确认报文能够到达B。这个ACK报文有可能丢失,使得处于LAST-ACK状态的B收不到确认,因此,B超时重传FIN+ACK报文段,而A能在2MSL时间内收到这个重传的FIN+ACK报文段,接着A重传一次确认,重新启动2MSL计时器,最后A和B都进入到CLOSE状态。若A不在TIME-WAIT状态等待一段时间,而是发送完ACK报文段后立即释放连接,当ACK报文段丢失后,B就无法正常进入到CLOSE状态。
2)防止已失效的报文段出现在本连接中。A在发送完最后一个ACK报文段后,再经过2MSL后,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现旧的报文段。
三、连接建立与释放过程中的标志位
SYN 同步,请求建立连接时使用。
FIN 释放连接,释放连接时使用。
ACK 确认,针对建立或释放连接的回复确认。