网络
TCP相关
如何保证可靠传输
三次握手建立连接
序列号和确认号保证有序传输
每个数据带有序号 seq,接收方返回 ack 告知发送方已接受到数据,可以继续发送
重传机制
- 超时重传,超时还未收到 akc 后,重传可能丢失的数据
- 快速重传,当连续收到三个相同 ack 后,立即重传可能丢失的数据
流量控制
维护一个代表接收能力的滑动窗口,若接收缓冲区快满了,就缩小窗口,反之扩大窗口
拥塞控制
网络拥堵时,TCP 会减慢发送速度,防止因网络拥堵丢失大量数据
四次挥手断开连接
三次握手
假设客户端为 A,服务器为 B
- 第一次握手(SYN)
- A 发送一个 SYN 包给 B,请求建立连接
- 进入
SYN_SENT
状态
- 第二次握手(SYN-ACK)
- B 收到后,回复一个 SYN-ACK 包,表示同意连接,并请求建立反方向连接
- B 进入
SYN_RCVD
状态 - 此时为半连接队列
- 第三次握手(ACK)
- A 收到后,发送一个 ACK 包给 B,表示连接建立成功
- A 进入
ESTABLISHED
状态,B 收到ACK后也进入ESTABLISHED
状态 - 此时为全连接队列
此时,连接正式建立,双方向都可以开始发送数据了
为什么不是两次?
两次只进行到 B 回复 SYN-ACK 包,A 只知道 B 收到了自己的请求,但不知道 B 是否准备好接受数据
为什么不是四次?
三次已经保证双方都能接收和发送数据,无需再做一次
也可以将 B 给 A 的包拆成 SYN 和 ACK 分开发送,但没必要
四次挥手
假设客户端为 A,服务器为 B
第一次挥手(FIN)
A 发送一个 FIN 报文,表示它已经没有数据要发送了,请求关闭连接
第二次挥手(ACK)
B 收到 FIN 报文后,发送一个 ACK 报文作为确认。此时 A 到 B 的数据通道关闭,但 B 还可以继续发数据给 A
第三次挥手(FIN)
B 完成自己的数据发送后,也发送一个 FIN 报文,请求关闭连接
第四次挥手(ACK)
A 收到 FIN 报文后,发送一个 ACK 报文确认。此时,整个连接关闭
进入 TIME_WAIT
强制等待 2MSL(两倍最大报文段生存时间),即一个来回的时间
防止旧连接中还在路上的数据包被新连接接收
确保最后一个 ACK 被对方收到,保证整个连接关闭
为什么不能三次?
TCP 是双向通信,双方都可以接收和发送数据,三次挥手只能关闭一个方向,导致一方的数据未发完
为什么不是五次?
四次已经能实现双向关闭,额外的操作会浪费资源
TIME_WAIT 过多
占用大量端口,影响并发性能
解决方案
- 端口复用
- 使用长连接
网络模型
OSI 七层模型
自上而下
- 应用层:HTTP、HTTPS
- 表示层:SSL/TLS
- 会话层:RPC
- 传输层:TCP、UDP
- 网络层:IP
- 数据链路层:以太网
- 物理层:光纤、网线
五层模型
自上而下
- 应用层:HTTP、HTTPS
- 传输层:TCP、UDP
- 网络层:IP
- 数据链路层:以太网
- 物理层:光纤、网线
TCP/IP 四层模型
自上而下
- 应用层:HTTP、HTTPS
- 传输层:TCP、UDP
- 网络层:IP
- 网络接口层:以太网、WIFI
网络 I/O 模型
I/O 多路复用
一个或少量线程/进程中同时监听多个 I/O 事件,提高系统效率,适用于高并发场景
Select
早期的I/O多路复用机制,使用固定长度的数组表示文件描述符集。每次调用select
时都需要重新构建和检查文件描述符集
支持的文件描述符数量有限(通常为1024),在大规模连接的场景下效率较低
Poll
poll
与select
类似,但使用动态数组来存储文件描述符,因此没有select
的最大连接数限制
每次调用时仍需遍历全部描述符,在处理大量连接时效率不高
Epoll
基于事件机制的 I/O 多路复用,当事件发生时,才会通知程序
LT 水平触发
只要时间处于活跃状态,就会一直通知程序,可能导致程序收到大量重复通知,增加开销
ET 边缘触发
仅在事件状态发生时通知程序,提高系统效率
ET 模式下如何保证数据全部读完?
ET 模式下,内核只通知一次,所以你必须循环读取直到读不到数据为止,即读取返回 EAGAIN
或 EWOULDBLOCK
1 | while (true) |
网络问题排查
客户端发送数据给服务器,服务器没反应
send() 返回成功后,数据一定发送出去了吗?
send()
返回成功只代表数据已成功复制到内核的发送缓冲区,不代表数据已经真正通过网络发送或对方已接收
- 数据仍可能滞留在发送缓冲区
- 如果网络出现拥堵或对方不可达,数据可能延迟或丢失
- TCP 的可靠性体现在协议层的重传和确认机制,应用层仅能确认数据进入内核缓冲区
网络攻击
DDoS
攻击者通过大量肉鸡,向目标服务器发送海量请求,耗尽其带宽、CPU、内存,导致服务器瘫痪,无法为正常用户提供访问
常见攻击方式
- 流量型:UDP 洪水,直接用流量压垮
- 协议型:SYN 洪水、Ping of Death,利用协议漏洞让服务器耗尽资源
- 应用层攻击:HTTP 请求洪水,高频率模拟正常用户操作
防护措施
- CDN 或 WAF 缓解压力
- 启用速率限制、IP黑名单
- 及时识别异常流量模式