网络穿透技术详解:TCP打洞、UDP打洞与UPnP
创作时间:
作者:
@小白创作中心
网络穿透技术详解:TCP打洞、UDP打洞与UPnP
引用
CSDN
1.
https://m.blog.csdn.net/problc/article/details/142280471
在现代网络环境中,许多设备都位于NAT(网络地址转换)或防火墙之后,这使得直接访问这些设备变得困难。网络穿透技术应运而生,其中TCP打洞、UDP打洞和UPnP是最常用的三种方法。本文将详细介绍这些技术的工作原理,并提供具体的代码示例。
一、TCP打洞
1.1 什么是TCP打洞?
TCP打洞(TCP Hole Punching)是一种使NAT后的两个客户端通过第三方服务器建立直接连接的方法。NAT通常会阻止外部主机直接与内部主机通信,因此需要借助外部服务器来协调连接。
1.2 工作原理
- 建立与中继服务器的连接:两个NAT后的客户端A和B先分别与公共服务器S建立连接。
- 交换外部地址:服务器S了解A和B的外部IP和端口,并将这些信息发送给彼此。
- 尝试直接连接:A和B分别尝试使用彼此的外部IP和端口进行连接,如果两端的NAT设备允许,则连接成功。
1.3 示例代码
以下是一个简单的Python示例,演示了通过TCP打洞进行连接的过程。
import socket
# Server listens for incoming connections and exchanges client information
def server():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('0.0.0.0', 12345))
s.listen(2)
print("Server waiting for connections...")
conn_a, addr_a = s.accept()
print(f"Client A connected: {addr_a}")
conn_b, addr_b = s.accept()
print(f"Client B connected: {addr_b}")
# Exchange addresses
conn_a.send(f"{addr_b[0]}:{addr_b[1]}".encode())
conn_b.send(f"{addr_a[0]}:{addr_a[1]}".encode())
conn_a.close()
conn_b.close()
s.close()
# Clients attempt to connect to each other using exchanged information
def client():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('server_ip', 12345)) # Replace 'server_ip' with the actual IP of the server
peer_info = s.recv(1024).decode()
peer_ip, peer_port = peer_info.split(':')
# Attempt to connect to peer
try:
peer_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
peer_socket.connect((peer_ip, int(peer_port)))
print("Connected to peer!")
except Exception as e:
print(f"Failed to connect to peer: {e}")
s.close()
二、UDP打洞
2.1 什么是UDP打洞?
UDP打洞(UDP Hole Punching)与TCP打洞类似,是一种让处于NAT后的两台主机通过第三方服务器建立直接UDP连接的技术。与TCP不同的是,UDP是无连接的协议,允许NAT主机更容易接受来自外部的连接请求。
2.2 工作原理
- 与服务器通信:两台客户端A和B分别与公共服务器S进行通信,服务器记录它们的外部IP和端口。
- 交换地址:服务器将A和B的外部IP和端口互相传递。
- 直接发送UDP数据包:A和B尝试通过彼此的外部地址直接发送UDP数据包,利用NAT会话表进行数据传输。
2.3 示例代码
import socket
# UDP Server to exchange addresses
def udp_server():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('0.0.0.0', 12345))
print("Server waiting for messages...")
data_a, addr_a = s.recvfrom(1024)
print(f"Received from A: {addr_a}")
data_b, addr_b = s.recvfrom(1024)
print(f"Received from B: {addr_b}")
# Exchange addresses
s.sendto(f"{addr_b[0]}:{addr_b[1]}".encode(), addr_a)
s.sendto(f"{addr_a[0]}:{addr_a[1]}".encode(), addr_b)
# UDP Client to communicate through hole punching
def udp_client():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(b'Hello from client', ('server_ip', 12345)) # Replace 'server_ip' with actual server IP
peer_info, _ = s.recvfrom(1024)
peer_ip, peer_port = peer_info.decode().split(':')
# Send message to peer
s.sendto(b'Hello peer!', (peer_ip, int(peer_port)))
try:
response, _ = s.recvfrom(1024)
print(f"Received from peer: {response}")
except socket.timeout:
print("No response from peer")
s.close()
三、UPnP(通用即插即用)
3.1 什么是UPnP?
UPnP(Universal Plug and Play,通用即插即用)是一种网络协议,允许设备自动发现和与网络中的其他设备进行通信。在NAT环境下,UPnP可以自动打开路由器的端口,从而允许外部设备访问位于内网中的设备。
UPnP主要用于家庭网络和小型局域网,它通过设备的自动配置来简化网络中的设备通信过程。
3.2 工作原理
- 设备发现:客户端设备通过发送SSDP(简单服务发现协议)请求,查找网络中的UPnP设备。
- 获取路由器的设备描述:通过SSDP发现的设备提供一个设备描述XML文件,描述其功能和端点。
- 请求端口映射:客户端通过向路由器发送请求,要求映射一个外部端口到内网设备的特定端口。
3.3 示例代码
可以使用第三方库miniupnpc
来实现UPnP端口映射,以下是一个Python示例。
pip install miniupnpc
import miniupnpc
def upnp_port_mapping():
upnp = miniupnpc.UPnP()
upnp.discoverdelay = 200
upnp.discover() # Discover UPnP devices
upnp.selectigd() # Select Internet Gateway Device
external_port = 12345
internal_port = 54321
local_ip = upnp.lanaddr # Get local IP address
# Add port mapping (TCP)
upnp.addportmapping(external_port, 'TCP', local_ip, internal_port, 'Test Port Mapping', '')
print(f"Port {external_port} mapped to {local_ip}:{internal_port} (TCP)")
# Optionally, remove the port mapping
# upnp.deleteportmapping(external_port, 'TCP')
upnp_port_mapping()
四、总结
- TCP打洞:通过第三方服务器交换外部地址,尝试建立直接的TCP连接。
- UDP打洞:类似TCP打洞,但使用UDP协议,更容易成功。
- UPnP:通过自动化的端口映射,使内网设备更易于被外部设备访问。
这三种技术在P2P应用中非常重要,特别是在NAT或防火墙环境下,它们能够显著提高连接的成功率。
热门推荐
《橘子不是唯一的水果》:人生不设限的隐喻
探索法律模糊区域:灰色地带的法律界定与法律责任
雾化异丙托溴铵和布地奈德可以一起使用吗
雾化异丙托溴铵和布地奈德可以一起使用吗
打工仔外賣推介!營養師嚴選外賣及出街食的健康之選
为什么富硒的东西被认为是好东西?
怎么让手机不再录音
苏姓起名6个思路,苏姓配什么名好听
ESFJ人格类型全面解析及相关特质
宝宝出生“最佳月份”,儿科医生:这个阶段是福气
如何分析黄金价格涨跌?从基本面到技术面的全面解析
深圳人才引进租房补贴怎么申请?
2024百度热搜年度报告:从热搜看中国人的年度记忆
教育部阳光高考平台:高考公平的守护者
公司法务部实习:法律实务与职业发展的深度探索
女人的内心世界,渴望被理解和呵护
2024年,社保补缴需要满足什么条件?哪些情况可以补缴?
荆州的七星宴:一道道承载着历史记忆的美食
合合王国新手攻略:四大资源获取全解析
如何解决团队孤立现象
吕不韦之死:自尽而亡背后的四点原因
太火爆!上海此地1天涌入超4万人......今年还有“新玩法”?
百日祭祀:中国传统丧葬文化中的孝道传承
非全日制本科可以考公务员吗?报考条件是什么?
天安门前的华表:从纳谏木柱到文化图腾
台州这些学校的“高颜值”板书,火了!舍不得擦
基金要怎么买才能把风险降到最低?全面解析与实战指南
结节患者饮食注意事项
揭开毛遂自荐背后的成语故事,探寻古人的智慧与幽默
毛遂自荐:古代自我推荐的典范