三次握手和四次挥手
在客户端和服务器进行数据传输前会经历三次握手和四次挥手,那三次握手和四次挥手具体是做了些什么呢?
三次握手
含义:三次握手其实是指在客户端和服务端建立一个TCP连接时,会经历总共发送3个包;
目的: 是为了确保双方的发送和接收是否正常,并指定自己的初始化序列号为后面正常传输数据做准备。
状态:
初始状态:客户端-closed 服务端-listen
第一次握手:客户端发送数据包:SYN=1,seq=x
客服端发送一段SYN(同步序列编号)的报文,指明客户端初始化序列号ISN。
注:
SYN: 用于建立连接的同步序列号 SYN=1,表示一个连接请求,握手完成后会变为0
seq: 客户端的序列号x
状态: 客户端-SYN_SENT
第二次握手:服务端发送数据包:SYN=1, seq=y,ACK=1, ack=x(客服端的seq)+1
服务端接收客户端报文后,将客户端的SYN+1作为ACK 的值,并返回发送自己的SYN报文和初始化序列号ISN(server);
注:
ACK: 确认序列号是否有效标识,1为有效,0为无效
ack:确认序列号,值为对方序列号+1
seq: 服务器的序列号y
状态:服务端-SYN_RCVD
第三次握手:客户端发送数据包: ACK=1, seq=x+1, ack=y(服务端的seq)+1
客户端接收到服务端的报文后,会返回发送一个 ACK 报文(服务端的seq+1)和自己的序列号
注:
ACK: 确认序列号是否有效标识,1为有效,0为无效
ack:确认序列号,值为对方序列号+1
seq: 自己初始+1
状态:客户端-ESTABLISHED 服务端-ESTABLISHED
为什么要三次握手
确认对方的发送和接收能力
第一次握手:客户端=》服务端-----服务端确认了客服端发送能力
第二次握手:服务端=》客户端-----客户端确认了服务端的接收和发送能力
第三次握手:客服端=》服务端-----服务端确认了客服端的接收能力
半连接队列:
服务端在第一次接收客服端SYN之后,会处于SYN_RCVD状态,此时服务端会把客服端的请求放在队列里,这种队列就是半连接队列;
在半连接队列的客服端如果在定时的时候没有收到客服的ACK,则会重发服务端ACK报文(linux 默认5次),超过则会断开连接;
半连接队列满:服务端会直接丢弃当前客户端 SYN 包(Client端由于多次重发SYN包得不到响应而抛出connection time out错误)
全连接队列
三次握手完成的连接会放入全连接状态
SYN攻击
SYN攻击是短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,server则回复ack确认包,由于源ip地址是伪造的,客服端不会有回复,server就不断的重发直至超时,此时伪造的大量的SYN包会占用半连接队列,导致正常的SYN请求因队列满被丢弃,从而引进网络瘫痪甚至系统瘫痪。
常见防御方法:
缩短SYN Timeout时间,增加最大半连接数,过滤网关防护,SYN cookies技术
四次挥手
TCP提供了在一端结束发送的同时可以保留接收数据能力,即TCP的half-close(半关闭),因此结束一段连接需要四次挥手。
第一次挥手 客户端发送报文段:FIN=1,seq=u
客户端断开连接,并发送(连接释放报文端)即FIN报文,报文中携带一段序列号seq。
状态:客户端-FIN_WAIT1 等待服务端的确认
第二次挥手 服务端发送报文段:ACK=1,ack=u+1,seq=v
服务端接收到客服端的释放连接报文后,发送确认报文段。此时TCP连接处于半关闭状态。
客户端接收到确认报文段后,处于FIN_WAIT2状态,继续等待服务端的连接释放报文段
状态:客户端-FIN_WAIT2 服务端-CLOSE_WAIT
第三次挥手 服务端发送报文段:FIN=1,ACK=1,seq=w ack=u+1
服务端断开连接,和客户端一样发送一段FIN报文,等待客户端的确认
状态:服务端-LAST_ACK
第四次挥手 客户端发送报文段:ACK=1,seq=u+1,ack=w+1
客户端接收到服务端的连接释放报文后,发出确认报文端。服务端接收确认报文段后就关闭连接,进入CLOSED状态,客户段处于TIME_WAIT(时间等待)状态,等待2MSL(报文在网络中最大生存时间)后进入关闭状态;
状态:服务端-CLOSED 客户端- TIME_WAIT
为什么要四次挥手
第一次和第二次为客户端关闭连接报文和服务端确认报文,第二次第三次为服务端关闭连接和客户端确认报文
客户端为什么要等待2MSL
确保服务端正常关闭连接。客户端在发送服务端的确认报文后,如果确认报文在发送的过程中丢失,服务端接收不到客户端的确认报文,会一直处于LAST-ACK状态,无法正常关闭。服务端如果超时没接收到客户端的确认报文,会重发FIN_ACK报文段,客户端接收后重置2MSI等待时间。