TCP三次握手
例:B向A发起连接:
每一次握手即是发送一个TCP包。SYN、ACK、FIN、seq、ack都是Tcp头部的标志位或数据位,读者不懂建议先作了解,可以更好的理解这篇文章。
-
第一次握手 B->[SYN],seq->A
发送一个TCP头部为标志位中仅SYN=1,seq数据序号位随机数初始化的tcp包。SYN标志代表这是一个发起连接包。此时B的状态位SYN_SEND。 -
第二次握手 A->[SYN-ACK],ack,seq->B
发送一个TCP头部为标志位中仅SYN=1/ACK=1,ack确认序号位=对方发送的的发起连接包中seq+1,也以随机数设置自己的seq数据序号的TCP包发送回B。这是一个连接确认包,A的状态位LISTEN变为SYN_RECV。 -
第三次握手 B->[ACK],ack->A
检查接受到的ack确认序号是否等于自己之前发送的seq数据序号+1,发送一个TCP头部为标志位中仅ACK=1,ack确认序号=对方发送的的发起连接包中seq+1。连接建立成功,双方状态ESTABLISHED。
针对三次握手的SYN攻击:
- 半连接状态:服务端接受到SYN请求连接包,并且发回SYN-ACK,等待客户端发回ACK时的状态就是半连接状态。
- 未连接队列:在三次握手中,服务端维持了一个半连接状态的队列。
- SYN-ACK重传次数和半连接存在时间。
SYN攻击原理:通过ip欺骗向服务端发送大量的半连接请求,耗费CPU和内存资源。
四次挥手:
例:B向A主动关闭连接
-
第一次挥手,B->[FIN],seq->A
B状态:ESTABLISHED->FIN_WAIT -
第二次挥手,A->[ACK],ack->B
A状态:ESTABLISHED->CLOSE_WAIT -
第三次挥手,A->[FIN-ACK],seq->B
A状态:LAST_ACK -
第四次挥手,B->[ACK],ack->A
B状态:TIME_WAIT,,等待2MSL后,A/B变为CLOSE状态。
之所以挥手比握手多一次的原因:
三次握手时连接时服务端的LISTEN状态下的SOCKET当收到SYN报文的连接请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。
关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可能未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
第四次挥手等待2MSL的原因:
为了保证B发送的最后一个ACK报文能够到A。等待一段时间以便在丢失的情况下超时重发报文。