三次握手
开始客户端处于close状态,服务端处于listen状态。
1、第一次握手:客户端给服务器发送一个 SYN 报文,同时发送一个序列号(ISN),进入SYN_Send状态。
2、第二次握手:服务器收到 SYN 报文之后,会应答一个 SYN+ACK (客户端发送的ISN+1)报文,同时发送一个序列号(ISN),进入SYN_REVD状态。
3、第三次握手:客户端收到 SYN+ACK 报文之后,会回应一个 ACK (服务端发送的ISN+1)报文,进入 establised状态。
4、服务器收到 ACK 报文之后,进入 establised状态,三次握手建立完成。
作用:
1、确认客户端、服务端发送、接收能力正常
2、指定自己的初始序列号,为可靠传送做准备。
3、若是 https 协议的话,三次握手还会进行数字证书的验证以及加密密钥的生成等
四次挥手:
1、第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于FIN_WAIT1状态。
2、第二次握手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 + 1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT状态,客户端进入FIN_WAIT2状态。
3、第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 状态。
4、第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 + 1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态
5、服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态
可能面试问题:
1、(ISN)序列号是固定的吗?
答:不固定,序列号动态生成,不然攻击者很容易猜出后续确认号
2、什么是半连接队列?
答:服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为半连接队列。当然还有一个全连接队列,就是已经完成三次握手,建立起连接的就会放在全连接队列中。如果队列满了就有可能会出现丢包现象。SYN-ACK 重传次数的问题:服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传。如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。
注意,每次重传等待的时间不一定相同,一般会是指数增长,例如间隔时间为 1s,2s,4s,8s…
3、三次握手过程中可以携带数据吗?
答:第一次、第二次握手不可以携带数据,而第三次握手是可以携带数据的。如果第一次可以携带数据,攻击者一直进行第一次握手携带大量数据,服务器要花费很多的时间和内存来接受报文。第三次客户端已经进入establised状态,他知道服务端的发送和接受能力正常,可以携带数据。
4、请讲一下TIME_WAIT状态(2MSL等待状态)
答: TIME_WAIT 持续的时间至少是一个报文的来回时间,因此是2MSL。理论上,四个报文都发送完毕,就可以直接进入CLOSED状态了,但是可能网络是不可靠的,有可能最后一个ACK丢失,那么服务器端就无法正常进入closed状态。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。