网络穿透:TCP 打洞、UDP 打洞与 UPnP

在现代网络中,很多设备都处于 NAT(网络地址转换)或防火墙后面,这使得直接访问这些设备变得困难。在这种情况下,网络穿透技术就显得非常重要。本文将介绍三种常用的网络穿透技术:TCP 打洞、UDP 打洞和 UPnP。
在这里插入图片描述

一、TCP 打洞

1.1 什么是 TCP 打洞?

TCP 打洞(TCP Hole Punching)是一种使 NAT 后的两个客户端通过第三方服务器建立直接连接的方法。NAT 通常会阻止外部主机直接与内部主机通信,因此需要借助外部服务器来协调连接。

1.2 工作原理

  1. 建立与中继服务器的连接:两个 NAT 后的客户端 A 和 B 先分别与公共服务器 S 建立连接。
  2. 交换外部地址:服务器 S 了解 A 和 B 的外部 IP 和端口,并将这些信息发送给彼此。
  3. 尝试直接连接: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 addressesconn_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 serverpeer_info = s.recv(1024).decode()peer_ip, peer_port = peer_info.split(':')# Attempt to connect to peertry: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 工作原理

  1. 与服务器通信:两台客户端 A 和 B 分别与公共服务器 S 进行通信,服务器记录它们的外部 IP 和端口。
  2. 交换地址:服务器将 A 和 B 的外部 IP 和端口互相传递。
  3. 直接发送 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 addressess.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 IPpeer_info, _ = s.recvfrom(1024)peer_ip, peer_port = peer_info.decode().split(':')# Send message to peers.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 工作原理

  1. 设备发现:客户端设备通过发送 SSDP(简单服务发现协议)请求,查找网络中的 UPnP 设备。
  2. 获取路由器的设备描述:通过 SSDP 发现的设备提供一个设备描述 XML 文件,描述其功能和端点。
  3. 请求端口映射:客户端通过向路由器发送请求,要求映射一个外部端口到内网设备的特定端口。
    在这里插入图片描述

3.3 示例代码

可以使用第三方库 miniupnpc 来实现 UPnP 端口映射,以下是一个 Python 示例。

pip install miniupnpc
import miniupnpcdef upnp_port_mapping():upnp = miniupnpc.UPnP()upnp.discoverdelay = 200upnp.discover()  # Discover UPnP devicesupnp.selectigd()  # Select Internet Gateway Deviceexternal_port = 12345internal_port = 54321local_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 或防火墙环境下,它们能够显著提高连接的成功率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/429688.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

qt-C++笔记之作用等同的宏和关键字

qt-C笔记之作用等同的宏和关键字 code review! Q_SLOT 和 slots: Q_SLOT是slots的替代宏,用于声明槽函数。 Q_SIGNAL 和 signals: Q_SIGNAL类似于signals,用于声明信号。 Q_EMIT 和 emit: Q_EMIT 是 Qt 中用于发射…

18.2K Star,AI 高效视频监控摄像头

Hi,骚年,我是大 G,公众号「GitHub 指北」会推荐 GitHub 上有趣有用的项目,一分钟 get 一个优秀的开源项目,挖掘开源的价值,欢迎关注。 导语 在家庭和企业安防领域,实时视频监控是保障安全的核…

AIGC8: 高通骁龙AIPC开发者大会记录B

图中是一个小男孩在市场卖他的作品。 AI应用开发出来之后,无论是个人开发者还是企业开发者。 如何推广分发是面临的大问题。 做出来的东西一定要符合商业规律。否则就是实验室里面的玩物,或者自嗨的东西。 背景 上次是回顾和思考前面两个硬件营销总的…

【JVM】类加载

1. 类加载过程 Java虚拟机(JVM)的 类加载 过程是将字节码文件(.class文件)从存储设备加载到内存,并为其创建相应的类对象的过程。类加载是Java程序运行的基础,保证了程序的动态性和安全性。JVM的类加载过程…

人工智能 | 基于ChatGPT开发人工智能服务平台

简介 ChatGPT 在刚问世的时候,其产品形态就是一个问答机器人。而基于ChatGPT的能力还可以对其做一些二次开发和拓展。比如模拟面试功能、或者智能机器人功能。 模拟面试功能包括个性化问题生成、实时反馈、多轮面试模拟、面试报告。 智能机器人功能提供24/7客服支…

将阮一峰老师的《ES6入门教程》的源码拷贝本地运行和发布

你好同学,我是沐爸,欢迎点赞、收藏、评论和关注。 阮一峰老师的《ES6入门教程》应该是很多同学学习 ES6 知识的重要参考吧,应该也有很多同学在看该文档的时候,想知道这个教程的前端源码是怎么实现的,也可能有同学下载…

esp32 wifi 联网后,用http 发送hello 用pc 浏览器查看网页

参考chatgpt Esp32可以配置为http服务器,可以socket编程。为了免除编写针对各种操作系统的app。完全可以用浏览器仿问esp32服务器,获取esp32的各种数据,甚至esp的音频,视频。也可以利用浏览器对esp进行各种操作。但esp不能主动仿…

【医学半监督】置信度指导遮蔽学习的半监督医学图像分割

摘要: 半监督学习(Semi-supervised learning)旨在利用少数标记数据和多数未标记数据训练出高性能模型。现有方法大多采用预测任务机制,在一致性或伪标签的约束下获得精确的分割图,但该机制通常无法克服确认偏差。针对这一问题,本文提出了一种用于半监督医学图像分割的新…

【C++笔记】C++编译器拷贝优化和内存管理

【C笔记】C编译器拷贝优化和内存管理 🔥个人主页:大白的编程日记 🔥专栏:C笔记 文章目录 【C笔记】C编译器拷贝优化和内存管理前言一.对象拷贝时的编译器优化二.C/C内存管理2.1练习2.2 C内存管理方式2.3 operator new与operator…

分布式锁优化之 使用lua脚本改造分布式锁保证判断和删除的原子性(优化之LUA脚本保证删除的原子性)

文章目录 1、lua脚本入门1.1、变量:弱类型1.2、流程控制1.3、在lua中执行redis指令1.4、实战:先判断是否自己的锁,如果是才能删除 2、AlbumInfoApiController --》testLock()3、AlbumInfoServiceImpl --》testLock() 1、lua脚本入门 Lua 教程…

长亭WAF绕过测试

本文的Bypass WAF 的核心思想在于,一些 WAF 产品处于降低误报考虑,对用户上传文件的内 容不做匹配,直接放行 0、环境 环境:两台服务器,一台配置宝塔面板,一台配置长亭雷池WAF 思路主要围绕:m…

Wpf使用NLog将日志输出到LogViewer

1 LogViewer LogViewer是通过UDP传输的高性能实时log查看器。 具有一下特性: 通过UDP读取日志通过文件导入日志导出日志到一个文件中排序、过滤(日志树,日志等级)和查找突出显示搜索文本从UPD接收日志时忽略IP地址列表多接收器支…

Java:Clonable 接口和拷贝

一 Clonable 接口 在 Java SE 中,Cloneable 是一个标记接口(Marker Interface),它位于 java.lang 包中。这个接口的主要目的是标识实现该接口的类能够被合法地克隆(即可以调用 Object 类中的 clone() 方法&#xff09…

【觅图网-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造…

神经网络面试题目

1. 批规范化(Batch Normalization)的好处都有啥?、 A. 让每一层的输入的范围都大致固定 B. 它将权重的归一化平均值和标准差 C. 它是一种非常有效的反向传播(BP)方法 D. 这些均不是 正确答案是:A 解析: ‌‌‌‌  batch normalization 就…

基于SpringBoot+WebSocket实现地图上绘制车辆实时运动轨迹图

实现基于北斗卫星的车辆定位和轨迹图的Maven工程(使用模拟数据),我们将使用以下技术: Spring Boot:作为后端框架,用来提供数据接口。Thymeleaf:作为前端模板引擎,呈现网页。Leaflet…

算法之逻辑斯蒂回归(Logistic regression)

简介:个人学习分享,如有错误,欢迎批评指正。 逻辑斯蒂回归(Logistic Regression)是统计学中一种广泛应用于二分类问题的算法。它的主要目标是预测二分类问题中的事件发生的概率。尽管名字里有“回归”,但逻…

高级I/O知识分享【epoll || Reactor ET,LT模式】

博客主页:花果山~程序猿-CSDN博客 文章分栏:Linux_花果山~程序猿的博客-CSDN博客 关注我一起学习,一起进步,一起探索编程的无限可能吧!让我们一起努力,一起成长! 目录 一,接口 epo…

【kaggle竞赛】毒蘑菇的二元预测题目相关信息和思路求解代码

毒蘑菇的二元预测 您提供了很多关于不同二元分类任务的资源和链接,看起来这些都是Kaggle竞赛中的参考资料和高分解决方案。为了帮助您更好地利用这些资源,这里是一些关键点的总结: Playground Season 4 Episode 8 主要关注的竞赛: 使用银行…

如何将很多个pdf拼接在一起?很多种PDF拼接的方法

如何将很多个pdf拼接在一起?将多个PDF文件合并不仅能够提升信息的整合性,还能使文件管理更加高效。想象一下,你需要向同事或老师提交一份综合报告,其中包含了多份相关资料。如果每个文件单独存在,查找和传输都会变得繁…