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(虽然严格来说不属于微任务,但行为类似且优先级更高)