Skip to content
 

TCP-IP协议和三次握手 ​

更新: 11/20/2025字数: 0 字 时长: 0 分钟

一、TCP/IP 概述 ​

首先,要澄清一个常见误区:TCP/IP 不仅仅指 TCP 和 IP 两个协议,而是一个庞大的协议族。

TCP/IP是互联网实际使用的协议族(而OSI是理论模型),由4 层构成:

TCP/IP 四层对应 OSI 层核心功能
应用层应用层/表示层/会话层提供用户服务(HTTP/FTP/DNS)
传输层传输层端到端通信(TCP/UDP)
网络层网络层寻址和路由(IP/ICMP)
网络接口层数据链路层/物理层物理传输(以太网/Wi-Fi)

区别

TCP/IP比 OSI 更简洁,将会话/表示层合并到应用层,数据链路/物理层合并为网络接口层。

TCP/IP 是实际实现,OSI 是理论模型

二、三次握手-建立连接 ​

三次握手是指在建立一个 TCP 连接时客户端和服务器总共要发送 3 个数据包以确认连接的建立。

三次握手的过程如下图所示:

TCP 三次握手

最开始时客户端和服务器都处于 CLOSED 状态。然后服务器主动监听某个端口(此时处于 LISTEN 状态)

2.1 第一次握手(由客户端发起) ​

客户端会随机初始化一个序列号(client_isn)然后发送一个带有 SYN seq = client_isn 信息的数据包。发送完成后客户端进入 SYN_SEND 状态(连接发送状态)

  • SYN 是一个标志位,为 1 时表示希望建立连接
  • seq = client_isn 是客户端随机初始化的序列号(一个 32 位的无符号数)

2.2 第二次握手(由服务器发起) ​

服务器收到客户端的 SYN 报文后,首先会随机初始化自己的序列号(server_isn)然后发送一个带有 SYN ACK seq = server_isn ack = client_isn + 1 信息的数据包。发送完成后服务器进入 SYN_RCVD 状态(连接收到状态)

  • ACK 是一个标志位,表示收到了请求
  • seq = server_isn 是服务器随机初始化的序列号(一个 32 位的无符号数)
  • ack = client_isn + 1 是一个确认应答号,值为客户端序列号 + 1

2.3 第三次握手(由客户端发起) ​

客户端收到服务器报文后,会再发送一个带有 ACK ack = server_isn + 1 信息的数据包。发送完成后客户端进入 ESTABLISHED 状态(连接成功状态)服务器收到客户端发送的应答报文包后也会进入 ESTABLISHED 状态

  • ack = server_isn + 1 是一个确认应答号,值为服务器序列号 + 1

三次握手可以保证客户端和服务器能够确认双方的接收和发送能力是否正常

  • 第一次握手:客户端发送 SYN 报文给服务器,服务器接收该报文
    • 客户端什么都不能确认
    • 服务器确认:自己接收正常,对方发送正常
  • 第二次握手:服务器发送 SYN + ACK 报文给客户端,客户端接收该报文
    • 客户端确认:自己发送正常、接收正常,对方发送正常、接收正常
    • 服务器确认:自己接收正常,对方发送正常
  • 第三次握手:客户端发送 ACK 报文给服务器
    • 客户端在第二次握手时已经完成确认
    • 服务器确认:自己发送正常,接收正常,对方发送正常、接收正常

三次握手的作用?

  1. 防止旧的重复连接初始化造成混乱
  2. 同步双方初始序列号(序列号能够保证数据包不重复、不丢弃和按序传输)
  3. 避免资源浪费

为什么不是两次握手?

两次握手无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号

为什么不是四次握手?

因为通过前三次已经可以建立一个可靠的连接,如果再发送第四次确认消息会浪费资源,所以不需要使用更多的通信次数

三次握手过程中,可以携带数据吗?

第一次、第二次握手不可以携带数据,第三次握手可以携带数据,因为在第三次握手时客户端已经处于连接状态,已经知道服务器的接收、发送能力是正常的

三、四次挥手-断开连接 ​

四次挥手是指断开一个 TCP 连接时客户端和服务器总共发送 4 个包以确认连接的断开,客户端和服务器双方都可以主动断开连接。

四次挥手的过程如下图所示:

TCP 四次挥手

最开始时客户端和服务器都处于 ESTABLISHED 状态

3.1 第一次挥手 ​

客户端先发送一个带有 FIN=1 信息的数据包,然后客户端进入 FIN_WAIT_1 状态

3.2 第二次挥手 ​

服务器收到客户端的 FIN 报文后,就向客户端发送 ACK 应答报文,然后服务器进入 CLOSED_WAIT 状态
当客户端收到服务器的 ACK 应答报文后会进入 FIN_WAIT_2 状态

3.3 第三次挥手 ​

当服务器处理完数据后,会向客户端发送 FIN 报文,之后服务器进入 LAST_ACK 状态

3.4 第四次挥手 ​

服务器收到服务器的 FIN 报文后,会回复一个 ACK 应答报文,之后进入 TIME_WAIT 状态
服务器收到了 ACK 应答报文后,就进入了 CLOSED 状态(服务器完成连接的关闭)
客户端在经过 2MSL 一段时间后会自动进入 CLOSED 状态(客户端完成连接的关闭)

什么是 MSL

MSL 是 Maximum Segment Lifetime(报文最大生存时间)是任何报文在网络上存在的最长时间,超过这个时间报文将会被丢弃

2MSL 的时间是从客户端接收到 FIN 后发送 ACK 开始计时的。如果在 TIME-WAIT 时间内,因为客户端的 ACK 没有传输到服务器,客户端又接收到了服务器重发的 FIN 报文,那么 2MSL 时间将重新计时

为什么挥手需要四次?

  • 在关闭连接时客户端向服务器发送 FIN 时,仅表示客户端不再发送数据了但是还能接收数据;
  • 当服务器在收到客户端的 FIN 报文时,会先回一个 ACK 应答报文,而服务器可能还有数据需要处理和发送,等服务器不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。

为什么需要 TIME_WAIT 状态?

主动发起关闭连接的一方才有 TIME-WAIT 状态

  1. 防止历史连接中的数据,被后面相同四元组的连接错误的接收;
  2. 保证被动关闭连接的一方,能被正确的关闭;

为什么 TIME_WAIT 等待的时间是 2MSL?

  1. 保证服务器能收到最后的 ACK 应答报文
  2. 让此次 TCP 连接中的所有报文在网络中消失,从而避免前后两个使用相同四元组的连接中的前一个连接的报文干扰后一个连接

假如客户端在送 ACK 后,这个 ACK 在 1MSL 时到达服务器,此时服务器在收到这个 ACK 的前一刹那,一直在重传 FIN,这个 FIN 最坏会在 1MSL 时间内消失。因此从客户端发送 ACK 的那一刹那开始,等待 2MSL 可以保证客户端发送的最后一个 ACK 和服务器发送的最后一个 FIN 都在网络中消失


更多细节

TCP 三次握手与四次挥手面试题 —— 小林 coding