马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
在当代网络中,许多装备都处于 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 示例。- 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 或防火墙情况下,它们可以大概明显进步毗连的乐成率。
|