面试题答案
一键面试TCP三次握手实现机制
- 内核管理TCP连接状态转换
- TCP连接有多个状态,如
CLOSED
(初始状态)、LISTEN
(服务器监听状态)、SYN_SENT
(客户端发送SYN包后状态)、SYN_RCVD
(服务器收到SYN包并回复SYN + ACK包后状态)、ESTABLISHED
(连接建立成功状态)。 - 客户端从
CLOSED
状态发送SYN
包后进入SYN_SENT
状态。服务器在LISTEN
状态收到SYN
包,回复SYN + ACK
包并进入SYN_RCVD
状态。客户端收到SYN + ACK
包,回复ACK
包并进入ESTABLISHED
状态,服务器收到ACK
包后也进入ESTABLISHED
状态。
- TCP连接有多个状态,如
- 数据包收发处理
- 客户端:在
CLOSED
状态下,应用层发起连接请求,内核TCP协议栈构造一个SYN
包(序列号seq = x
)发送出去。 - 服务器:在
LISTEN
状态下,内核TCP协议栈收到SYN
包,检查合法性,若合法则构造一个SYN + ACK
包(seq = y
,ack = x + 1
)发回给客户端。 - 客户端:收到
SYN + ACK
包,验证ack
和seq
,若正确则构造ACK
包(seq = x + 1
,ack = y + 1
)发送给服务器。 - 服务器:收到
ACK
包,验证ack
和seq
,若正确则连接建立成功。
- 客户端:在
- 缓冲区操作
- 发送缓冲区:客户端发送
SYN
包时,将其放入发送缓冲区等待发送。当收到对端确认(如服务器的SYN + ACK
包),相应数据可以从发送缓冲区移除(对于SYN
包本身)。 - 接收缓冲区:服务器收到
SYN
包,放入接收缓冲区,处理后将回复的SYN + ACK
包放入发送缓冲区。客户端收到SYN + ACK
包放入接收缓冲区,处理后将ACK
包放入发送缓冲区。
- 发送缓冲区:客户端发送
- 资源分配与回收
- 分配:在连接建立过程中,内核为连接分配资源,如为接收和发送缓冲区分配内存空间,为连接维护状态信息的结构体分配内存等。例如,在内核中为每个TCP连接创建一个
struct sock
结构体,用于存储连接的各种参数和状态。 - 回收:连接建立成功后,一些临时用于三次握手的资源(如特定的定时器等)可以回收。
- 分配:在连接建立过程中,内核为连接分配资源,如为接收和发送缓冲区分配内存空间,为连接维护状态信息的结构体分配内存等。例如,在内核中为每个TCP连接创建一个
TCP四次挥手实现机制
- 内核管理TCP连接状态转换
- 涉及状态有
ESTABLISHED
(连接已建立)、FIN_WAIT_1
(主动关闭方发送FIN
包后状态)、FIN_WAIT_2
(主动关闭方收到ACK
包后状态)、CLOSE_WAIT
(被动关闭方收到FIN
包后状态)、LAST_ACK
(被动关闭方发送FIN
包后等待ACK
的状态)、TIME_WAIT
(主动关闭方收到最后一个ACK
包后状态)、CLOSED
(连接关闭完成状态)。 - 主动关闭方在
ESTABLISHED
状态发送FIN
包进入FIN_WAIT_1
状态,被动关闭方收到FIN
包进入CLOSE_WAIT
状态并回复ACK
包,主动关闭方收到ACK
包进入FIN_WAIT_2
状态。被动关闭方准备好关闭时发送FIN
包进入LAST_ACK
状态,主动关闭方收到FIN
包回复ACK
包进入TIME_WAIT
状态,被动关闭方收到ACK
包进入CLOSED
状态,主动关闭方在TIME_WAIT
状态等待一段时间(2MSL)后进入CLOSED
状态。
- 涉及状态有
- 数据包收发处理
- 主动关闭方:在应用层发起关闭请求后,内核TCP协议栈构造
FIN
包(seq = u
)发送给被动关闭方,进入FIN_WAIT_1
状态。 - 被动关闭方:收到
FIN
包,验证seq
等,回复ACK
包(ack = u + 1
,seq = v
),进入CLOSE_WAIT
状态。 - 主动关闭方:收到
ACK
包,进入FIN_WAIT_2
状态。被动关闭方应用层发起关闭请求,内核TCP协议栈构造FIN
包(seq = v
)发送给主动关闭方,进入LAST_ACK
状态。 - 主动关闭方:收到
FIN
包,验证seq
等,回复ACK
包(ack = v + 1
,seq = u + 1
),进入TIME_WAIT
状态。被动关闭方收到ACK
包进入CLOSED
状态。
- 主动关闭方:在应用层发起关闭请求后,内核TCP协议栈构造
- 缓冲区操作
- 发送缓冲区:主动关闭方发送
FIN
包时,放入发送缓冲区。收到被动关闭方的ACK
包后,FIN
包相关数据可从发送缓冲区移除。同样,被动关闭方发送FIN
包也放入发送缓冲区,收到主动关闭方的ACK
包后移除。 - 接收缓冲区:主动关闭方收到被动关闭方的
FIN
包放入接收缓冲区,被动关闭方收到主动关闭方的FIN
包也放入接收缓冲区。
- 发送缓冲区:主动关闭方发送
- 资源分配与回收
- 分配:在挥手过程中,可能会分配临时资源用于处理关闭流程,如定时器等。
- 回收:连接完全关闭后,内核回收为该连接分配的所有资源,包括缓冲区内存、
struct sock
结构体等。
Linux内核实现特点与优化策略
- 特点
- 状态机实现:Linux内核通过状态机严格管理TCP连接状态转换,确保每个状态转换都符合TCP规范,并且在状态转换过程中执行相应的操作,如定时器管理、数据包处理等。
- 模块化设计:TCP协议栈在Linux内核中以模块化形式实现,各个模块负责不同功能,如连接管理、数据包收发、拥塞控制等,便于维护和扩展。
- 优化策略
- 快速打开:TCP Fast Open(TFO)允许客户端在首次连接时就发送数据,而无需等待完整的三次握手完成。服务器通过在
SYN + ACK
包中携带一个Cookie,客户端后续连接可以在SYN
包中带上该Cookie,服务器验证通过后直接进入ESTABLISHED
状态并处理数据。 - TIME_WAIT 优化:Linux内核采用多种方式优化
TIME_WAIT
状态。例如,tcp_tw_reuse
参数允许在一定条件下重用处于TIME_WAIT
状态的连接,减少资源占用。tcp_tw_recycle
参数可加速TIME_WAIT
状态连接的回收,但在NAT环境下可能有问题,所以默认关闭。 - 拥塞控制优化:Linux内核不断改进拥塞控制算法,如
reno
、cubic
等算法。cubic
算法通过更精确地探测网络拥塞情况,调整发送窗口,提高网络利用率和稳定性。
- 快速打开:TCP Fast Open(TFO)允许客户端在首次连接时就发送数据,而无需等待完整的三次握手完成。服务器通过在