三次握手
客户端发送一个 SYN消息, 服务端使用 SYN+ACK 应答表示收到这个消息, 客户端再以ACK 消息响应。
半连接队列
服务器会把只完成一次握手的请求,放在半连接队列。
全连接队列
服务器会把完成三次握手的请求,放在全连接队列, 如果队列溢出了会出现丢包的问题。
重传
如果客户端未收到服务端发送的报文, 服务端会重新传给客户端, 如果超出重传的最大次数, 会把请求从半连接队列中移除。每次等待的重传时间一般是指数递增的。
三次握手过程中可以携带数据吗?
第一次、第二次不行, 第三次可以。第一次是因为还未建立连接,客户端发送给服务器的数据, 服务器可能收不到;也可能会被攻击者利用SYN 攻击,给服务端发送大量无用的数据报文, 导致服务器压力变大。 第三次是因为客户端已经知道服务端的请求和接受数据能力正常,可恶意携带。
SYN攻击是什么?
伪造大量不存在的 SYN 包请求服务端, 服务端得不到客户端应答, 就会重复发送 ACK确认包,这些SYN 请求将会长时间占用服务端的半连接队列,导致正常的请求因为队列满而丢弃,从而引发网络拥塞和瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。
半关闭状态
客户端和服务端的接受和发送能力都是独立的,关闭某一端需要单独关闭接受和发送能力。
四次挥手
客户端和服务端都可以主动发起挥手动作, 发起挥手之前, 双方都是已连接状态。
客户端发送一个 FIN 消息并指定一个 sep 序号, 服务端收到后会发送 ACK 报文,并使用seq+1作为 ACK 报文的序列号,服务端发送一个 FIN 消息, 客户端再以 ACK 确认消息。
挥手为什么需要四次?
服务端收到 FIN 报文时, 并不会立即关闭连接,而是先 ACK 响应, 等服务端报文发送完毕, 再关闭发送能力。
为什么2MSL
第四次挥手时,客户端发出 ACK ,告诉服务端收到了 FIN 。
如果服务端没有收到 客户端发出了 ACK, 就会触发重传( 1 个MSL), 重新发送 FIN给客户端。 客户端收到重传后, 发送 ACK再次确认。 去向 ACK 的 MSL + 来向重传的 FIN 的 MSL = 2MSL;如果超过 2MSL后客户端未收到重传的 FIN,就会关闭接受能力,彻底关闭连接。
- 保证客户端发送的最后一个ACK报文段能够到达服务端。
- 防止“已失效的连接请求报文段”出现在本连接中