TCP/IP 协议三次握手（Three Way Handshake）

三次握手是用于建立客户端与服务器的 TCP 连接，确保连接是可靠的、同步的。

第一次握手：SYN

客户端向服务器发送一个 SYN（Synchronize）报文，表示请求建立连接。

客户端进入 SYN-SENT 状态，等待服务器响应。

Copy
客户端 - SYN ---> 服务器

第二次握手：SYN-ACK

服务器受到客户端的 SYN 报文后，回应一个 SYN-ACK（Synchronize Acknowledge）报文，表示接受并同意建立连接，同时也向客户端发送一个 SYN，请求建立反向连接。

服务器进入 SYN-RECEIVED 状态。

Copy
客户端 <--- SYN-ACK - 服务器

第三次握手：ACK

客户端收到服务器的 SYN-ACK 报文后，发送一个确认 ACK 报文，表示连接已建立。

客户端进入 ESTABLISHED 状态，服务器收到 ACK 后也进入 ESTABLISHED 状态。

Copy
客户端 - ACK ---> 服务器

三次握手的目的

确保双方能正确发送和接收数据，并同步双方的序列号。

解释 TCP 需要三次握手的原因

三次握手是为了确保双方都有发送和接收的能力（双方都要确认对方有发送和接收的能力）。

第一次握手：客户端告诉服务器，自己可以发送数据。

第二次握手：服务器告诉客户端，自己可以收发数据。

第三次握手：客户端告诉服务器，自己可以接收数据。

TCP/IP 协议四次挥手（Four Way Handshake）

四次回收用于断开客户端与服务器的连接，由于 TCP 是全双工协议，连接断开时需要双方各自关闭发送和接收通道，因此需要四次挥手来完成断开操作。

第一次挥手：FIN

客户端发送 FIN（Finish）报文，表示不再发送数据，但仍可以接收数据。

客户端进入 FIN-WAIT-1 状态。

Copy
客户端 - FIN ---> 服务器

第二次挥手：ACK

服务器受到客户端的 FIN 报文后，发送一个 ACK 报文，表示确认受到 FIN 报文，但服务器仍可能有数据需要发送。

服务器进入 CLOSE-WAIT 状态，客户端进入 FIN-WAIT-2 状态。

Copy
客户端 <--- ACK - 服务器

第三次挥手：FIN

服务器完成数据发送后，向客户端发送 FIN 报文，表示数据传输结束，准备关闭连接。

服务器进入 LAST-ACK 状态。

Copy
客户端 <--- FIN - 服务器

第四次挥手：ACK

客户端收到服务的 FIN 报文后，发送一个 ACK 报文，表示确认关闭连接。

客户端进入 TIME-WAIT 状态，等待一段时间（一般为 2 * MSL，最大报文存活时间）后，正式关闭连接，进入 CLOSED 状态。服务器在收到 ACK 后立即进入 CLOSED 状态。

Copy
客户端 - ACK ---> 服务器

简述 TCP 拥塞控制算法

慢启动：建立连接后，初始化发送窗口大小，随着每次发送 ACK 到达，窗口大小呈指数级增长，直到达到拥塞阀值。

拥塞避免：当窗口大小达到阀值后，发送方每次只增加一个 MSS。

快速重传：在没有等待超时的情况下，接收方连续发送 3 个重复的 ACK 时，发送方立即重传相应的报文段。

快速恢复：当进入快速重传阶段后，发送方将窗口减半。

简述 MTU 和 MSS

MTU（Maximum Transmission Unit）：最大传输单元，表示网络层一次能传输的最大数据包大小，以太网通常为 1500 Byte。

MSS（Maximum Segement Size）：最大报文段大小，TCP 层能够发送的单个数据段的最大字节数，通常是 MTU 减去 TCP/IP 头部大小。

TCP 粘包问题

当客户端发送多个数据包给服务器时，服务器底层的 TCP 接收缓冲区受到的数据为粘在一起的。

TCP 底层通信是面向字节流的，面向连接的协议，TCP 保证发送数据的准确性和顺序性，字节流以字节为单位。

假设 TCP 缓冲区的大小为 10 个字节，当发送 4 个字节的数据（"aaaa"），缓冲区还剩余 6 个字节的空闲空间，再次发送 7 个字节的数据（"bbbbbbc"），则客户端第一次接收的数据是 "aaaabbbbbb" ，剩余 1 个字节的数据未发送，等待下一次发送。

TCP 粘包产生的原因

多个小数据包在传输过程中粘在一起，接收端无法区分这些包的边界，导致接收到的数据合并在一起。

（发的太快）当客户端的发送频率远高于服务器的接收频率。

（发的太少）TCP 底层的安全和效率机制，其不允许字节数特别少的小包发送频率过高，TCP 会在底层累计到一定大小才一起发送。（Nagle）

（缓冲区残留）发送端的缓冲区中有上一次未发送完的数据，或接收端的缓冲区中有未取出的数据。

TCP 黏包处理的方式

主要采用应用层定义收发包格式的方法，俗称切包处理

使用 TLV 协议

TLV（Type Length Value）协议。

Copy
+---------+---------+---------+
| type | length | value |
+---------+---------+---------+

打包发送的数据，解包接收的数据。

使用分隔符

在报文之间增加特殊字符

设置固定长度的报文

规定报文的长度，接收方根据长度拆分。

TCP 实现全双工的方式

独立的发送和接收缓冲区，通信双方都有一个发送缓冲区和接收缓冲区，通信双方在发送数据时可以接收数据，反之依然。

独立的序列号和确认机制，TCP 将要发送的数据流切分为多个报文段，每个报文段的字节都有唯一的序列号，确保发送的数据包在整个数据流中的位置，接收方可以根据序列号判断数据的正确顺序以及是否有丢包。

流量控制，TCP 通过控制滑动窗口机制调整发送速率，保证不会让接收方的缓冲区溢出（被数据淹没）。

拥塞控制，控制通过调节发送方的发送速率来防止网络过载。