TCP的三次握手:
这个Sequence Number(seq)是用于TCP保证之后的数据的顺序(可能会因为网络上的问题而乱序),用这个seq拼接数据,所以客户端收到服务器发送来的seq之后,还要再发送一个ACk告诉服务器自己已经收到你的seq啦。
SYN超时
SYN超时:发生在首次握手之后,服务器收到了客户端的syn,回复Syn-Ack的时候,没有收到ACK,那么此时就处于连接没有开启也没有关闭的状态,服务端一直到达不了Syn-Recieve的状态,一直处于监听状态,那么这时候,Server端就一直重试(一直发送Syn-ACk),直至超时,Linux默认等待63s才断开此次连接。
(为啥是63s:默认重试五次,第一次时间间隔是1s,第二次是2s,三次是4s,四次8s,五次是16s,重试的第五次发出去之后,还需要等待32s,才会被判定为超时。总共时间间隔为63s。)
洪泛攻击
那么在这段时间内,可能会有SYN Flood的风险(洪泛攻击)。黑客就会利用伪造的IP地址像服务端不断的发送请求,却不发送ACk,那么本次的TCP连接就处于挂起的状态,服务端在等待关闭该连接的过程中耗尽了资源(收不到客户端的ACK,就会重复发送Syn-Ack,消耗内存和CPU,直至服务器宕机),正常的客户端发送的请求就得不到回应。
SYN Flood的防护措施
当SYN队列满了之后,通过tcp_syncookies参数回发SYN Cookie,(tcp_syncookies是通过源IP地址端口,目的地址端口和时间戳来确定的一个sequnce number)只有正常的客户端收到该cookie之后会回发 Syn Cookie,直接和服务端建立连接。
通过Syn cookie,即使当前的队列满了,当前连接不在队列中,依然可以建立连接。
保活机制
保活机制 由一个保活计数器实现。是服务器用来确认什么时候应该断开连接的一种机制。
保活功能可以被设置在TCP连接的一端、两端,或者两端都没有。
如果建立了连接之后,客户端出现了故障怎么办?
保活机制:在keep alive time保活时间内处于非活动状态,那么开启保活机制的一端向对方发送保活探测报文,如果(在保活时间间隔内keep alive interval)没有收到响应就继续发送,直到达到了保活探测的次数(keep alive probe),对方被确认为不可达,本次连接中断。
保活结果:
TCP的三次挥手
客户端为啥有一个TIME_WAIT状态:
- 确保有足够的时间让对方收到ACK包;(如果被动端没有关闭的话,就会触动主动端重发FIN包,一来一去,就是2MSL)
- 避免新旧连接混淆。有些路由器会缓存没有收到的数据包,如果新的连接开启,这些数据包可能就会和新的连接中的数据包混在一起。
为啥有四次握手 才能断开连接
因为TCP是全双工的,所以发送方和接收方都需要SYN报文ACK报文。两方各自需要两次握手。
服务器出现大量的CLOSE_WAIT状态的原因
根据TCP四次挥手的图示可以看出,出现Close_wait的情况是在服务器没有继续发送Fin_ACK报文导致的。
也就是 对方已经关闭socket连接,我方忙于读或者写,没有及时关闭连接。
出现原因:代码中有资源释放的地方出错了;或者配置中出处理请求的线程配置出错了。