TCP/IP 的三次握手和四次挥手
- 简述TCP三次握手过程
在TCP/IP协议中,TCP协议提供可靠的连接服务,采取三次握手建立一个连接,
UDP是不可靠的
C(客户端) S (服务端)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201222192405941.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTg1MzUzMw==,size_16,color_FFFFFF,t_70![在这里插入图片描述](https://img-blog.csdnimg.cn/20201222192820455.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTg1MzUzMw==,size_16,color_FFFFFF,t_70
第一次握手
建立连接时, c发送 SYN=1 SEQ=X到服务器,并进入SYN-SEND状态,等待服务器确认;
第二次握手
服务器收到SYN包,必须确认客户的SYN ACK=X+1,同时自己也发送一个自己的序列号SEQ=Y,此时服务器进入SYN_RECV状态;
第三次握手
客户端收到服务器的SYN+ACK 包,向服务器发送确认包ACK(ACK=Y+1),此同时产生自己的序列号,包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
完成三次握手,客户端与服务器开始传送数据
SYN攻击:
在三次握手过程中,Server发送SYN-ACK之后,收到Client的ACK之前的TCP连接称为半连接(half-open connect)(第二次的握手过程中),此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESTABLISHED状态。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将产时间占用未连接队列,导致正常的SYN请求因为队列排满而被丢弃,从而引起网络堵塞甚至系统瘫痪。
SYN攻击时一种典型的DDOS攻击,检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定遭到SYN攻击了,使用如下命令可以让之现行:
netstat -n| awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’ tcp状态
- 四次挥手
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201222193523514.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTg1MzUzMw==,size_16,color_FFFFFF,t_70
FIN_WAIT_1
这个状态和FIN_WAIT_2状态都在再等待对方的回复,但是这两种状态是有区别的,FIN_WAIT_1就是主动方在ESTABLISHED状态的时候,想要主动关闭连接,向对方发送FIN报文,这时候就进入了FIN_WAIT_1状态。当他收到对方回复的ACK报文后,就进入了FIN_WAIT_2状态。 但是在实际操作中是很难遇到FIN_WAIT_1状态的,因为无论对方是什么情况都应该立刻回应ACK报文,但是FIN_WAIT_2状态还是可以在主动方中用netstat看到的。
FIN_WAIT_2
上面已经对FIN_WAIT_2讲解过了,当主动方进入FIN_WAIT_2时,就表示着半连接状态,也就是主动方还有数据要发给对方,这个数据就是之后的ACK,所有他要等一会儿才关闭连接。
CLOSE_WAIT
这个状态从表面也可以看出它的作用,就是等待关闭。当被动方接收到FIN时,会立刻回复一个ACK给对方,接下来就是进入CLOSE_WAIT状态。在这个状态中,被动方需要考虑自己还有没有数据要发送给对方,如果有可以继续发送,如果没有了就可以关闭连接了,发送一个FIN给对方。 这个状态其实也就是给自己一个缓冲的时间,让自己处理完需要处理的事,然后去关闭连接。
TIME_WAIT
这个状态就是一段时间后进行一些操作。当主动方收到了对方发来的FIN报文,并发出ACK报文,接下来就等2MSL就可以进入CLOSED状态了。其实,如果主动方在FIN_WAIT_1状态下,收到了对方的FIN+ACK标志的报文,就可以跳过FIN_WAIT_2状态直接进入TIME_WAIT状态了。
LAST_ACK
这个状态从表面不难不理解他的意思,这个状态就是被动方发送了FIN报文后,最后等待对方的ACK报文,收到ACK报文后就可以进入CLOSED状态了。
CLOSED
上面提到了几次这个状态,相比也猜出来了,这个状态表示的就是连接中断,已经关闭。
为什么需要TIME_WAIT?
TIME_WAIT在四次挥手中有着不可替代的位置,如果没有TIME-WAIT,主动方就会直接进入CLOSED状态,(假设主动方时客户端,被动方时服务端)这时候如果立即重启客户端使用相同的端口,如果因为网络中种种原因最后一次ACK丢失了,服务端就会重复FIN请求,这时这个FIN就会被重新启动的客户端接收到,或者新启动的客户端向服务端发起请求的时候,因为服务端正在等待最后一次ACK,因此新连接请求发送的SYN就会被服务端认为时请求码错误,服务端就会回复RET重置连接。所以就需要主动方发送最后一次ACK之后进入TIME_WAIT状态,等待2MSL(两个报文最大生命周期),等待这段时间就是为了如果接收到了重发的FIN请求能够进行最后一次ACK回复,让在网络中延迟的FIN/ACK数据都消失在网络中,不会对后续连接造成影响
那么为什么TIME_WAIT的时间是2MSL呢?
MSL是TCP报文的最大生命周期,因为TIME_WAIT持续在2MSL就可以保证在两个传输方向上的尚未接收到或者迟到的报文段已经消失,否则服务器立即重启,可能会收到来自上一个进程迟到的数据,但是这种数据很可能是错误的,同时也是在理论上保证最后一个报文可靠到达,假设最后一个ACK丢失,那么服务器会再重发一个FIN,这是虽然客户端的进程不在了,但是TCP连接还在,仍然可以重发LAST_ACK。