通过公网STUN服务器实现UDP打洞
-
- 一、背景介绍
- 二、原理详解
-
- 1、NAT的工作原理
- 2、STUN服务器的作用
- 3、UDP打洞的核心思想
- 三、NAT类型对比详解
- 四、测试结果分析
- 五、详细操作步骤
-
- 1、环境准备
- 2、代码
- 3、完整操作流程
-
- 3.1、在两台设备上运行脚本
- 3.2、交换公网地址信息
- 3.3、同步开始打洞
- 3.4、验证连接
- 六、实际应用场景
- 七、总结
一、背景介绍
在当今互联网环境中,很多设备都位于NAT(网络地址转换)设备之后,这导致设备之间无法直接建立P2P连接。UDP打洞技术正是为了解决这一问题而诞生的。
什么是UDP打洞? 想象一下,两个人都住在不同的公寓楼里(NAT后面),他们想直接通话而不是通过中间人转接。UDP打洞就像是通过一个公共的\”介绍人\”(STUN服务器)让双方知道对方的\”窗户位置\”(公网IP和端口),然后同时向对方的窗户喊话,从而建立直接的联系。
二、原理详解
1、NAT的工作原理
NAT设备就像是大楼的保安,它:
- 将内部设备的私有IP地址转换为公共IP地址
- 记录内部设备发起的连接,并管理返回的数据包
- 通常拒绝外部设备直接发起的连接请求
2、STUN服务器的作用
STUN(Session Traversal Utilities for NAT)服务器是一个公网上的\”镜子\”,它告诉你:
- 你的设备在公网上的IP地址和端口号
- 你的NAT类型和行为特征
3、UDP打洞的核心思想
三、NAT类型对比详解
| Open Internet | 无NAT | 直接连接 | 住在街边独栋,门牌号公开 |
| Full Cone NAT | 完全开放 | 容易 | 公寓保安记住你的脸,任何人都能进来找你 |
| Restricted Cone NAT | 中等 | 中等 | 保安只允许你联系过的人进来找你 |
| Port Restricted Cone NAT | 较严格 | 较难 | 保安不仅看脸,还要看具体的\”敲门方式\” |
| Symmetric NAT | 最严格 | 最难 | 每次联系不同的人,保安都给不同的门禁卡,无法预测 |
四、测试结果分析
为什么有些组合能成功,有些不能?
-
✅ 二边都是Restricted NAT:可以打通
- 因为双方都先\”认识\”了对方(通过STUN服务器间接接触)
- NAT设备会允许来自\”认识的人\”的连接
-
❌ 任意一边是Symmetric NAT:不能打通
- Symmetric NAT每次对外连接都用不同的端口
- 对方无法预测你会用哪个端口来接收数据
- 就像每次用不同的电话号码打电话,对方无法回拨
五、详细操作步骤
1、环境准备
首先确保你的Python环境已就绪:
# 检查Python版本
python3 –version
# 安装必要的库
pip3 install pystun3
2、代码
cat > hole_punching_utils.py << \’EOF\’
import threading
import socket
import random
import select
import time
import socket
import binascii
import stun
import socket
import struct
import random
def is_udp_port_free(host=\’localhost\’, port=0):
\”\”\”检查UDP端口是否空闲\”\”\”
try:
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.bind((host, port))




