三次握手的流程是:客户端发送 SYN 报文表示请求建立连接,服务端回复 SYN+ACK 表示同意并确认,客户端再回一次 ACK,连接正式建立。之所以是三次而不是两次,是为了防止历史连接(旧的请求报文延迟到达)被误建立,同时确认双方的收发能力都正常。
四次挥手因为 TCP 是全双工的,关闭需要双向各自确认:主动方发 FIN,被动方回 ACK 后进入 CLOSE_WAIT,被动方处理完数据再发 FIN,主动方回 ACK 并等待 2MSL 后关闭。面试常追问 TIME_WAIT 的作用,一是保证最后的 ACK 能重传,二是让旧报文在网络中消失。
// 三次握手与四次挥手的过程示意 const shake = [ 'C -> S: SYN seq=x,客户端进入 SYN_SENT', 'S -> C: SYN+ACK seq=y ack=x+1,服务端进入 SYN_RCVD', 'C -> S: ACK ack=y+1,双方进入 ESTABLISHED' ]; const wave = [ 'C -> S: FIN,主动方进入 FIN_WAIT_1', 'S -> C: ACK,被动方进入 CLOSE_WAIT', 'S -> C: FIN,被动方进入 LAST_ACK', 'C -> S: ACK 并等待 2MSL,TIME_WAIT 后关闭' ]; [...shake, '--- 断开连接 ---', ...wave].forEach(s => console.log(s));