006-TCP和UDP

TCP与UDP协议深度解析

一、传输层核心概念

1.1 传输层作用

  • 进程到进程通信:与网络层的”主机到主机”通信互补
  • 多路复用/解复用:通过端口号区分不同应用
  • 可靠性保障(TCP):确保数据完整有序到达
  • 流量控制:防止发送方淹没接收方

1.2 协议栈位置

+---------------------+
|     应用层 (HTTP)    |
+---------------------+
|     传输层 (TCP/UDP) |
+---------------------+
|     网络层 (IP)      |
+---------------------+
|   数据链路层 (以太网) |
+---------------------+

二、TCP协议深度解析

2.1 TCP核心特性

可靠性保障机制

  1. 序列号与确认应答(SEQ/ACK)

    • 每个字节都有唯一序列号
    • 接收方通过ACK确认已收到数据
    • 示例:ACK=1001表示已收到1-1000字节
  2. 超时重传

    • RTO(Retransmission Timeout)动态计算:
      RTO = SRTT + max(G, K×RTTVAR)
      其中SRTT是平滑往返时间,RTTVAR是方差
  3. 数据排序

    • 通过序列号重组乱序到达的报文段

流量控制

  • 滑动窗口协议
    • 接收方通过窗口字段通告可用缓冲区大小
    • 发送方根据窗口大小调整发送速率
  • 零窗口探测:当窗口为0时发送探测报文

拥塞控制

  1. 慢启动

    • 窗口从1 MSS开始指数增长
    • 到达阈值(ssthresh)后进入拥塞避免
  2. 拥塞避免

    • 窗口线性增长
    • 出现丢包时调整ssthresh
  3. 快速重传

    • 收到3个重复ACK立即重传
    • 不等待超时计时器
  4. 快速恢复

    • 重传后窗口减半
    • 直接进入拥塞避免阶段

2.2 TCP头部结构

 0                   1                   2                   3   
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+---------------+---------------+---------------+---------------+
|     Source Port (16)         |   Destination Port (16)        |
+---------------+---------------+---------------+---------------+
|                       Sequence Number (32)                    |
+---------------+---------------+---------------+---------------+
|                     Acknowledgment Number (32)                |
+---------------+---------------+---------------+---------------+
|  Data | Reserved | Control | Window Size (16)                 |
| Offset|          | Flags   |                                 |
+---------------+---------------+---------------+---------------+
|     Checksum (16)            |  Urgent Pointer (16)           |
+---------------+---------------+---------------+---------------+
|                    Options (0-40 bytes, optional)            |
|                   + Padding to 32-bit boundary               |
+---------------+---------------+---------------+---------------+
|                             Data                              |
+---------------+---------------+---------------+---------------+

关键字段说明

  • 控制标志位
    • SYN:建立连接
    • ACK:确认有效
    • FIN:关闭连接
    • RST:重置连接
    • PSH:推送数据(立即处理)
    • URG:紧急指针有效
  • 窗口大小:接收方可用缓冲区字节数
  • 选项字段
    • MSS(最大报文段长度)
    • 窗口缩放因子
    • 时间戳(用于RTT计算)

2.3 TCP连接管理

三次握手(连接建立)

  1. 客户端发送SYN(SEQ=x)
  2. 服务端回复SYN-ACK(SEQ=y, ACK=x+1)
  3. 客户端发送ACK(ACK=y+1)

状态变迁

CLOSED → SYN_SENT → ESTABLISHED (客户端)
CLOSED → LISTEN → SYN_RCVD → ESTABLISHED (服务端)

四次挥手(连接关闭)

  1. 主动方发送FIN(SEQ=u)
  2. 被动方回复ACK(ACK=u+1)
  3. 被动方发送FIN(SEQ=v)
  4. 主动方回复ACK(ACK=v+1)

状态变迁

ESTABLISHED → FIN_WAIT_1 → FIN_WAIT_2 → TIME_WAIT → CLOSED (主动方)
ESTABLISHED → CLOSE_WAIT → LAST_ACK → CLOSED (被动方)

2.4 TCP高级特性

选择性确认(SACK)

  • 解决多个包丢失时的效率问题
  • 通过TCP选项字段通告不连续的数据块
  • 示例选项格式:
    Kind=5 Length=10 Left Edge=1001 Right Edge=2000

时间戳选项

  • 计算精确RTT(往返时间)
  • 防止序列号回绕(PAWS机制)
  • 格式:
    Kind=8 Length=10 Timestamp Value=12345678 Timestamp Echo Reply=0

三、UDP协议深度解析

3.1 UDP核心特性

无连接服务

  • 无需建立/维护连接
  • 每个数据报独立处理

不可靠传输

  • 不保证交付
  • 不保证顺序
  • 无拥塞控制

轻量级头部

 0                   1                   2                   3   
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+---------------+---------------+---------------+---------------+
|     Source Port (16)         |   Destination Port (16)        |
+---------------+---------------+---------------+---------------+
|      Length (16)             |     Checksum (16)              |
+---------------+---------------+---------------+---------------+
|                             Data                              |
+---------------+---------------+---------------+---------------+

字段说明

  • 长度字段:包括头部和数据的总长度(最小8字节)
  • 校验和:可选(IPv4),强制(IPv6)

3.2 UDP适用场景

  1. 实时应用

    • 视频会议(WebRTC)
    • 在线游戏(FPS/MOBA)
    • VoIP(如SIP协议)
  2. 广播/多播

    • DHCP发现
    • 视频流分发
  3. 简单查询

    • DNS查询
    • SNMP监控
  4. 自定义可靠协议

    • QUIC(HTTP/3基础)
    • 某些P2P协议

3.3 UDP优势与局限

优势:

  • 低延迟:无连接建立开销
  • 低开销:头部仅8字节(TCP至少20字节)
  • 无阻塞控制:适合容忍丢包的应用
  • 支持多播:TCP只能单播

局限:

  • 需要应用层处理可靠性
  • 易受DDoS攻击(如UDP洪水)
  • 可能加剧网络拥塞

四、TCP与UDP对比

特性 TCP UDP
连接方式 面向连接(三次握手) 无连接
可靠性 可靠(确认、重传) 不可靠
流量控制 滑动窗口机制
拥塞控制 复杂算法(慢启动等)
数据顺序 保证按序到达 不保证顺序
头部开销 最小20字节 8字节
传输方式 字节流 数据报文
适用场景 文件传输、网页浏览 实时视频、DNS查询
多播支持 不支持 支持
资源消耗 高(维护连接状态)

五、协议选择策略

5.1 选择TCP的场景

  • 需要可靠交付(如文件传输)
  • 需要严格数据顺序(如数据库同步)
  • 传输大量数据(HTTP下载)
  • 无法容忍数据丢失(金融交易)

5.2 选择UDP的场景

  • 低延迟优先(实时游戏)
  • 简单查询响应(DNS)
  • 广播/多播需求(视频会议)
  • 自定义可靠协议(QUIC)
  • 容忍数据丢失(语音通话)

5.3 混合使用案例

视频会议系统:

  • 信令控制:TCP(SIP协议)
  • 媒体传输:UDP(RTP协议)
  • 补充机制:应用层重传关键帧

六、高级主题与演进

6.1 TCP优化技术

BBR拥塞控制算法

  • Google开发的基于带宽时延积的算法
  • 特点:
    • 测量实际带宽和RTT
    • 主动探测瓶颈带宽
    • 在丢包率高时仍保持高吞吐

Multipath TCP

  • 同时使用多个网络路径
  • 应用场景:
    • 手机WiFi和4G同时使用
    • 数据中心多网卡绑定

6.2 UDP的创新应用

QUIC协议

  • 基于UDP的可靠传输协议
  • HTTP/3的基础
  • 特性:
    • 0-RTT连接建立
    • 改进的拥塞控制
    • 连接迁移支持

WebRTC

  • 浏览器实时通信框架
  • 使用UDP传输媒体流
  • 应用层实现:
    • 丢包重传(NACK)
    • 前向纠错(FEC)
    • 拥塞控制(GCC算法)

七、协议分析实践

7.1 Wireshark抓包分析

TCP连接示例:

No.  Time        Source        Destination   Protocol Info
1    0.000000   192.168.1.2   93.184.216.34  TCP      [SYN] Seq=0
2    0.028415   93.184.216.34 192.168.1.2    TCP      [SYN, ACK] Seq=0 Ack=1
3    0.028472   192.168.1.2   93.184.216.34  TCP      [ACK] Seq=1 Ack=1

UDP数据报示例:

No.  Time        Source        Destination   Protocol Info
1    0.000000   192.168.1.2   8.8.8.8       DNS      Standard query A example.com
2    0.032158   8.8.8.8       192.168.1.2   DNS      Standard query response A 93.184.216.34

7.2 性能测试工具

iPerf测试TCP吞吐量:

1
2
3
4
5
# 服务端
iperf3 -s

# 客户端
iperf3 -c server_ip -t 30 -w 256K

UDP带宽测试:

1
iperf3 -c server_ip -u -b 100M -t 20

八、安全考量

8.1 TCP安全威胁

SYN Flood攻击

  • 攻击原理:发送大量SYN不完成握手
  • 防御方案:
    • SYN Cookie
    • 连接速率限制

序列号预测

  • 早期系统使用可预测的ISN
  • 现代系统使用加密哈希生成ISN

8.2 UDP安全威胁

反射放大攻击

  • 利用DNS/NTP等服务响应大于请求的特性
  • 防御:
    • 禁用开放递归DNS
    • 入口过滤(BCP38)

UDP洪水攻击

  • 消耗目标带宽资源
  • 缓解方案:
    • 限速
    • 流量清洗

九、协议演进趋势

9.1 TCP发展

  • TCP Fast Open:允许在SYN阶段携带数据
  • TCP ECN:显式拥塞通知
  • TCP-AO:更安全的认证选项

9.2 UDP创新

  • QUIC标准化:成为HTTP/3基础
  • UDP-Lite:部分校验和(适合有纠错的应用)
  • UDT:基于UDP的高速数据传输协议

通过这种深度技术解析,可以全面理解TCP和UDP的设计哲学、实现细节以及适用场景,为网络编程和协议选择提供坚实基础。实际应用中应根据业务需求、网络环境和性能要求做出合理选择。

003-浏览器与Node事件循环

浏览器与Node.js事件循环(Event Loop)详解

浏览器事件循环(Event Loop)

1. 基本概念

浏览器的事件循环是JavaScript实现异步编程的核心机制,它负责协调用户交互、脚本执行、渲染、网络请求等事件。

2. 运行机制

主要组成部分:

  • **调用栈(Call Stack)**:执行同步代码的栈结构
  • **任务队列(Task Queue)**:
    • 宏任务队列(Macrotask Queue)
    • 微任务队列(Microtask Queue)
  • Web APIs:浏览器提供的异步API环境

执行流程:

  1. 执行全局同步代码(同步任务直接进入调用栈执行)
  2. 遇到异步操作时:
    • 宏任务(setTimeout、setInterval、I/O等)交给Web APIs处理,完成后回调放入宏任务队列
    • 微任务(Promise.then、MutationObserver等)回调放入微任务队列
  3. 当调用栈为空时:
    • 先检查微任务队列并执行所有微任务
    • 然后从宏任务队列取出一个任务执行
  4. 重复上述过程

图示流程:

[执行同步代码] → [微任务队列全部执行] → [渲染(如有需要)] → [取一个宏任务执行] → [重复]

3. 任务分类

宏任务(Macrotasks):

  • script整体代码
  • setTimeout/setInterval
  • I/O操作
  • UI渲染
  • postMessage
  • MessageChannel
  • setImmediate(仅IE/Node.js)

微任务(Microtasks):

  • Promise.then/catch/finally
  • MutationObserver
  • process.nextTick(Node.js特有)
  • queueMicrotask

4. 执行顺序示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
console.log('script start');

setTimeout(() => {
console.log('setTimeout');
}, 0);

Promise.resolve().then(() => {
console.log('promise1');
}).then(() => {
console.log('promise2');
});

console.log('script end');

// 输出顺序:
// script start
// script end
// promise1
// promise2
// setTimeout

Node.js事件循环

1. 基本概念

Node.js使用libuv库实现的事件驱动架构,其事件循环比浏览器更复杂,分为多个阶段。

2. 阶段划分

完整事件循环阶段(按顺序执行):

  1. timers阶段:执行setTimeout和setInterval的回调
  2. pending callbacks阶段:执行某些系统操作的回调(如TCP错误)
  3. idle, prepare阶段:Node内部使用
  4. poll阶段
    • 检索新的I/O事件
    • 执行I/O相关回调(几乎所有的回调,除了close、timers和setImmediate)
    • 可能会阻塞在此阶段等待新事件
  5. check阶段:执行setImmediate的回调
  6. close callbacks阶段:执行关闭事件的回调(如socket.on(‘close’))

3. 特殊队列

nextTick队列

  • process.nextTick()的回调
  • 不属于事件循环的任何阶段
  • 在当前操作完成后立即执行,优先级高于微任务

微任务队列

  • 包括Promise.then、queueMicrotask等
  • 在每个阶段之间执行

4. 执行顺序规则

  1. nextTick队列 > 微任务队列 > 其他阶段
  2. 每个阶段执行完毕后,都会先执行完nextTick队列和微任务队列

5. 与浏览器的区别

  1. 阶段划分不同:Node.js有明确的阶段划分
  2. 优先级不同:
    • Node.js中:process.nextTick > Promise微任务
    • 浏览器中:Promise微任务 > setTimeout宏任务
  3. 实现机制不同:Node.js基于libuv,浏览器基于HTML5规范

6. 执行顺序示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
console.log('start');

setTimeout(() => {
console.log('timer1');
Promise.resolve().then(() => {
console.log('promise1');
});
}, 0);

setTimeout(() => {
console.log('timer2');
Promise.resolve().then(() => {
console.log('promise2');
});
}, 0);

Promise.resolve().then(() => {
console.log('promise3');
});

process.nextTick(() => {
console.log('nextTick');
});

console.log('end');

/* Node.js输出顺序:
start
end
nextTick
promise3
timer1
promise1
timer2
promise2
*/

常见面试问题解答

Q1: 浏览器和Node.js事件循环的主要区别?

  1. 阶段划分:Node.js有明确的6个阶段,浏览器更简单
  2. 任务优先级:Node.js中process.nextTick优先级最高
  3. 实现机制:Node.js使用libuv,浏览器遵循HTML5规范
  4. 微任务执行时机:Node.js在每个阶段之间执行微任务

Q2: process.nextTick和setImmediate的区别?

  • process.nextTick()
    • 在当前阶段立即执行
    • 优先级高于微任务
  • setImmediate()
    • 在check阶段执行
    • 属于宏任务

Q3: 为什么Promise.then比setTimeout先执行?

因为Promise.then属于微任务,会在当前宏任务执行完后立即执行所有微任务,而setTimeout是下一个宏任务。

Q4: Node.js中哪些操作会产生微任务?

  • Promise.then/catch/finally
  • async/await
  • queueMicrotask
  • process.nextTick(虽然严格来说不属于微任务,但行为类似且优先级更高)