在线咨询
在线客服

工作日:9:00-24:00

商务合作

15366085265

QQ联系方式

1872421339

大客户经理

宋经理

客户经理
专业客户经理,解答您的疑问

SOCKS5 UDP 流程:一次真正的 UDP 代理是如何跑起来的?

发布日期

一、为什么 SOCKS5 需要支持 UDP?

许多实时应用,如游戏、语音、DNS、QUIC,都依赖 UDP 才能实现低延迟与快速响应。

TCP 的握手、顺序控制、拥塞控制等特性虽然可靠,却不适合实时业务。因此 SOCKS5 必须提供 UDP 中继能力,让客户端在不直接暴露网络环境的情况下发送原始 UDP 数据。

二、SOCKS5 UDP 的完整流程(四步)

1. TCP 握手(Hello)
2. 认证(可选)
3. UDP ASSOCIATE:申请“UDP 中继通道”
4. 通过中继端口发送封装后的 UDP 数据

三、步骤 1:TCP 握手(Hello)

客户端首先通过 TCP 与代理服务器建立控制通道,用来协商认证方式。

客户端发送:
VER NMETHODS METHODS...

示例:
05 02 00 02   # 版本5,支持无认证与用户名密码

服务器回应:

05 00   # 版本5,选择无认证

四、步骤 2:认证(如需)

若服务器要求用户名密码认证,客户端会发送以下结构:

VER ULEN USER PLEN PASS

服务器返回认证是否成功:

VER STATUS
01 00   # 00 表示成功

五、步骤 3:UDP ASSOCIATE(核心步骤)

UDP ASSOCIATE 是整个 SOCKS5 UDP 流程中最关键的一步。客户端通过它向服务器申请一个 UDP 中继端口。

客户端请求格式:

VER CMD RSV ATYP DST.ADDR DST.PORT

其中:CMD=03 表示 UDP ASSOCIATE。

服务器响应格式:

VER REP RSV ATYP BND.ADDR BND.PORT

注意:服务器返回的 BND.ADDR / BND.PORT 是客户端之后 **必须发送 UDP 包的地址**,不是目标服务器的地址。

六、步骤 4:UDP 包封装与转发

1. 客户端发送 UDP 包前,必须进行封装:

+----+------+------+----------+----------+----------+
|RSV | FRAG | ATYP | DST.ADDR | DST.PORT |   DATA   |
+----+------+------+----------+----------+----------+
| 2  |  1   |  1   | Variable |    2     | Variable |

解释:

• RSV:保留字段,必须为 00 00
• FRAG:分片编号,一般为 00
• ATYP:地址类型(IPv4/域名/IPv6)
• DST.ADDR/DST.PORT:真实目标地址
• DATA:原始 UDP 数据包

2. 示例封装:

假设我们向 8.8.8.8:53 发送 DNS 查询,原始 UDP Payload:

12 ab 01 00 ...

封装后的 SOCKS5 UDP 包:

00 00 00 01 08 08 08 08 00 35 12 ab 01 00 ...

3. 代理服务器收到后做什么?

代理服务器会执行:

1. 解析 SOCKS5 UDP Header
2. 提取 DST.ADDR/DST.PORT
3. 将 DATA 作为真正的 UDP 包发给目标服务器

4. 回包如何返回客户端?

流程刚好相反:

目标服务器 → 代理 → 封装 SOCKS5 UDP 头 → 客户端

七、UDP ASSOCIATE 不是“建立 UDP 连接”

这是常见误区。UDP 无连接,因此:

• UDP ASSOCIATE 不会建立持久连接
• 它只是创建一个“UDP 中继上下文”
• 所有真实的 UDP 包必须单独封装并发送

八、为什么很多 SOCKS5 实现不支持 UDP?

原因如下:

• UDP 需要 NAT 映射保持,成本高
• 防火墙经常阻断 UDP
• 服务器需要额外管理多个中继端口
• 回包难以追踪来源
• 一旦高并发,会话维护成本巨大

九、哪些场景最依赖 SOCKS5 UDP?

• 游戏代理(UDP 高并发)
• DNS 代理(53 端口)
• QUIC(HTTP/3)
• 实时语音、实时视频
• 各类自定义 UDP 协议

十、总结:理解 SOCKS5 UDP,你必须记住三句话

1. UDP ASSOCIATE 返回的是“中继端口”,不是目标服务器。
2. 所有 UDP 包都必须加 SOCKS5 封装头。
3. 客户端 ↔ 代理是封装后的 UDP;代理 ↔ 目标是原始 UDP。