1.说说TCP三次握手
1.0 在此之前,什么是TCP?
TCP(传输控制协议)
1.面向连接的,可靠的,基于字节流的传输层通信协议
2.将应用层的数据流分割成报文段并发送给目标节点的TCP层
3.数据包都有序号,对方收到则发送ACK确认,未收到则重传
4.使用校验和来检验数据在传输过程中是否有误
**注: ACK--确认序号标志,即接收端实体对已成功收到的包的确认,(确认后+1)
SYN--同步序号,用于建立连接过程
在连接请求中,SYN=1,ACK=0-->该数据段没有使用捎带的确认域,SYN=1,ACK=1-->连接应答捎带一个确认域
FIN:finish标志,用于释放连接,等于1时,表示发送方已经没有数据发送,即关闭数据流
Sequence Numbe:数据包的序号,用来保证不丢包
1.1 "握手"是为了连接,TCP三次握手如上图所示
**图注:第一次握手,seq-->初始序号,x是任意正整数.发送的不能携带数据,但是,要消耗掉一个序号.
第二次握手,如果同意连接,就发出确认报文,ack=x+1(第一次握手中seq=x,1即上一个报文消耗的序列),同时,为自己的缓存初始化序列号,即seq=y,SYN-RCVD:同步收到状态.(也不能携带数据,并且也要消耗一个序号)
第三次握手,当TCP客户进程收到确认报文之后,还要向服务器给出确认,ack=y+1(上一次seq=y,1是小号的序号),seq=x+1(先前告知客户端序号+1),此时,客户端连接建立,ESTAB-LESHED(已建立连接状态),TCP规定,第三次握手的时候可以(也不是必须,如果不携带数据,就不会消耗序号)携带数据
当服务器接收到后,也进入,ESTAB-LESHED(已建立连接状态),,双方开始通信
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接
第1次握手:建立连接时,客户端发送SYN包(syn=j)到服务器,并进入 SYN_SENT(同步已发送)状态,等待服务器确认
第2次握手:服务器收到SYN包,必须确认客户的SYN(ack=j+1),同时,自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RCVD状态;
第3次握手:客户端接收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTAB-LISHED状态,完成三次握手.
1.2 为什么需要三次握手才能建立连接
为了初始化Sequence Number的初始值,通信的双方要互相通知对方,自己的初始化的Sequence Number,也就是上图中的x和y,这个Number要作为以后的数据通信的序,以保证接收到的数据不会因为网络的问题而乱序,即TCP会用这个序号来拼接数据,因此,在服务器回发他的Sequence Number(第二次握手之后),还需要发送确认报文给服务器,告知服务器,客户端已接收到你发的初始化的Sequence Number了.
1.3 首次捂手的隐患---SYN超时
问题起因:
Server收到Client的SYN,回复SYN-ACK时没有收到ACK确认
Server不断重试直到超时,linux默认重试次数为5次,时间从一秒开始,每次翻倍. 5次总共31s,在第五次发出去之后还需要等待32s才能被判定为超时,总共31+32=63s,此时TCP断开连接.
后果:
可能会让服务器遭到SYN Flood的风险.
解决方案:
linux下,SYN队列满后,通过tcp_syncookies(Sequence Number的简称)参数回发SYN Cookie
若正常连接则Client会回发SYN Cookie,直接建立连接