TCP三次握手
三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实质上其实就是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号,交换TCP窗口大小信息。
一、握手过程
-
刚开始客户端处于 Closed 的状态,服务端处于 Listen 状态。
-
第一次握手:客户端向服务器发送
SYN报文
请求连接,报文中指明同步位SYN为1,初始序列号seq。此时客户端处于SYN_SEND
状态。 -
第二次握手:服务器收到该客户端报文后,会向客户端发送
SYN+ACK确认连接报文
,
该报文指明ACK=1,确认号ack为客户端序列号+1,表明服务器已收到客户端报文,同时指定自己的序列号seq和设置同步位SYN为1。此时服务器处于SYN_RECVD
状态。 -
第三次握手:客户端收到服务器报文后,会回复一个确认报文,该报文指明ACK为1,确认号ack为服务器的序列号+1,表明已收到服务器报文,此时客户端处于
ESTABLISH状态
,当服务器收到确认报文后,也处于ESTABLISH状态
,此时,双方已建立起了连接。
二、握手过程为什么要三次,两次不行吗?
-
需要三次握手才能保证客户端和服务器双方的收发信息能力是否正常。
-
第一次握手:客户端发包,服务器收到了
- 可得出的结论是,服务器可以确认自己的接收能力和客户端的发送能力是正常的
-
第二次握手:服务器发送网络包,客户端收到了
- 可得出的结论是,客户端可确认自己的发送和接收能力,还有服务器的发送和接收能力是正常的。
-
第三次握手:客户端发包,服务端收到了。
- 可得出的结论是,服务器的发送能力和客户端的接收能力是正常的
-
如果是两次握手,有可能出现的情况是:
- 失效的连接请求到达服务器,造成资源浪费
- 客户端发送连接请求报文到服务器,但因连接请求报文丢失而导致重发,第二次发送的报文成功和服务器建立连接,而第一次发送的连接请求报文可能由于网络阻塞,延误到在连接被释放后的某个时间点才到达服务器,此时服务器认为客户端又发起了的一次请求,于是向客户端发送确认报文,由于是二次握手,发出报文后就建立了连接。此时对于客户端来说,该请求报文已失效,所以不会响应服务器发送过来的确认报文,也不会发送数据,从而造成服务器资源浪费。
三、三次握手过程中是否可以携带数据?
- 第一次和第二次握手不可以携带数据,第三次握手可以,因为如果第一次和第二次握手可以携带数据,容易被攻击,攻击方不理会服务器的收发信息能力,在握手过程疯狂重复发送携带大量数据SYN报文,那服务器会花费很长时间、内存空间去处理数据。而第三次握手,客户端已经知道双方的接收和发送能力正常,所以可以发送数据。
四、SYN攻击(ddos攻击)
- 服务器的资源分配是在二次握手后完成分配的,客户端的资源分配是在三次握手后分配的,SYN攻击指的是攻击方在短时间内伪造大量不存在的ip地址,并向服务器不断发送SYN包,而服务器则会返回响应报文,由于地址不存在,服务器会不断的重发直至超时,这些伪造的SYN包将占用未连接队列,当队列满时,可能导致正常请求被丢弃,从而引起网络拥塞甚至系统瘫痪。通过增大最大半连接数、缩短超时时间,限制同ip访问并发数进行防范。
五、第三次握手失败会怎样?
- 对于服务端,在一定时间内未收到客户端的确认报文,则会进行重发,而如果在服务器还没接收到确认报文时(未建立连接),客户端往服务器发送数据(这时客户端是已经处于
ESTABLISH
状态),则服务器会返回RST
报文给客户端,进行重置连接。
四次挥手
建立一个连接需要三次握手,而终止一个连接要经过四次挥手(也有将四次挥手叫做四次握手的)。这由TCP的半关闭(half-close)造成的。所谓的半关闭,其实就是TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。
TCP 连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),客户端或服务端均可主动发起挥手动作。
一、挥手过程
- 第一次挥手:客户端向服务器发送
FIN
报文请求关闭连接,报文中会指定一个序列号。此时客户端处于FIN_WAIT_1
(终止等待1)状态,停止发送数据,主动关闭TCP连接,等待服务器应答。 - 第二次挥手:服务器收到
FIN
连接释放报文后,会发送ACK确认报文
给客户端,该报文指明确认号ack为客户端的序列号+1,表明服务器已经收到客户端报文了,此时服务器处于CLOSE_WAIT
状态,TCP处于半关闭状态,客户端到服务端的连接释放。客户端收到服务端的确认后,进入FIN_WAIT2
(终止等待2)状态,等待服务端发出的连接释放报文段。 - 第三次挥手:服务器确认没有数据要发送,就向客户端发送
FIN
连接释放报文,该报文会指定一个序列号,此时服务器处于LAST_ACK
状态。 - 第四次挥手:客户端收到服务器连接释放报文后,会发送
ACK确认报文
给服务器,该报文指明ack确认号为服务器序列号+1,表明客户端已收到服务器报文。此时客户端处于TIME_WAIT
状态。服务器收到确认报文后,则直接进入CLOSED
关闭状态。而客户端需要过一段时间以确保服务器收到确认报文后才会进入CLOSED
关闭状态。 - 此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。
二、为什么握手只需要三次,而挥手却需要四次?
- 因为在握手时,服务器接收到客户端的请求连接报文后,可以将ACK和SYN一起发送给客户端,而在挥手时,收到FIN连接释放报文后,仅仅表示客户端不再发送数据了,但是还能接收数据,所以不能立即关闭,需要将ACK和FIN分开发送。
三、四次挥手释放连接时,等待2MSL的意义?
MSL
是指报文在网络传输过程中的最长存活时间,超过这个时间的报文都会被丢弃。
- 1、为了保证客户端发送的最后一个ACK报文能到达服务器
- 2、防止当前的无效的报文出现在下一个新的连接中
参考链接:https://yuanrengu.com/2020/77eef79f.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。