CPP在内网穿透技术的思考
概述
内网穿透是一种技术,用于在私有局域网(LAN)中的设备与外部网络(如互联网)之间建立通信通道,使得外部设备可以访问内网中的服务。由于内网设备通常位于防火墙或 NAT(网络地址转换)设备之后,外部网络无法直接访问它们。因此,内网穿透技术旨在解决这一问题。本文将讨论如何使用 C++ 实现内网穿透技术,并介绍一些常见的实现方式。
一、内网穿透的基本原理
内网穿透的核心思想是通过一个中间服务器(通常位于公网中)来中转内网的请求。内网设备与外网设备通过这个中间服务器进行通信,避开防火墙或 NAT 设备的限制。具体流程包括以下步骤:
- 内网设备主动连接到中间服务器:由于 NAT 设备允许内部设备主动发起外部连接,因此内网设备可以与位于公网的中间服务器建立连接。
- 外网设备向中间服务器发出请求:外网设备通过公网 IP 地址访问中间服务器,请求访问内网中的服务。
- 中间服务器转发请求:中间服务器将外网设备的请求转发给已经连接的内网设备,内网设备响应后再通过中间服务器返回给外网设备。
二、常见的内网穿透技术实现手段
反向代理(Reverse Proxy) 反向代理是一种常见的内网穿透方式。使用反向代理时,内网设备主动与中间服务器建立连接,并保持连接的持续性。外网设备通过访问中间服务器获取内网服务。
- 实现思路:
- 使用 C++ 开发的客户端程序在内网设备上运行,主动连接位于公网的中间服务器(该服务器可以使用 C++ 通过 socket 实现)。
- 中间服务器充当代理,将外网的请求通过内网设备返回。
- C++ 示例: 下面展示了一个简单的反向代理服务器的基本结构:
#include <iostream>
#include <boost/asio.hpp> using boost::asio::ip::tcp; void start_server(boost::asio::io_context& io_context, short port) {
tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), port));
while (true) {
tcp::socket socket(io_context);
acceptor.accept(socket);
std::string message = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nHello from the proxy!";
boost::asio::write(socket, boost::asio::buffer(message));
}
} int main() {
boost::asio::io_context io_context;
start_server(io_context, 8080);
return 0;
}
- 实现思路:
TCP 隧道(TCP Tunneling) TCP 隧道是一种通过中间服务器将外网请求直接转发到内网设备的方法。外网设备与内网设备之间的数据流通过中间服务器进行封装和转发,内网设备将其解封装后处理请求。
实现思路:
- 使用 C++ 实现 TCP 隧道的功能,内网设备和外网设备同时与中间服务器保持连接。
- 外网设备发送请求时,中间服务器将数据包转发给内网设备处理。
C++ 示例:
#include <iostream>
#include <boost/asio.hpp> using boost::asio::ip::tcp; void start_server(boost::asio::io_context& io_context, short port) {
tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), port));
while (true) {
tcp::socket socket(io_context);
acceptor.accept(socket);
std::string message = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nHello from the proxy!";
boost::asio::write(socket, boost::asio::buffer(message));
}
} int main() {
boost::asio::io_context io_context;
start_server(io_context, 8080);
return 0;
}
UDP 打洞(UDP Hole Punching) UDP 打洞是一种广泛使用于 P2P 网络的技术。该技术通过让两个处于不同 NAT 后面的设备同时向一个中间服务器发送 UDP 数据包,从而建立起两者之间的直接通信。
实现思路:
- 使用 C++ 开发内网设备的 UDP 客户端,同时向中间服务器和目标设备发送数据包。
- 中间服务器在收到来自两个设备的请求后,向双方告知彼此的公网 IP 和端口号,进而双方可以通过该信息直接进行通信。
C++ 示例:
#include <iostream>
#include <boost/asio.hpp> using boost::asio::ip::tcp; void tunnel_data(tcp::socket& in_socket, tcp::socket& out_socket) {
char data[1024];
boost::system::error_code error;
size_t length = in_socket.read_some(boost::asio::buffer(data), error);
if (!error) {
boost::asio::write(out_socket, boost::asio::buffer(data, length));
}
} int main() {
boost::asio::io_context io_context; // Connect to the external client
tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), 8888));
tcp::socket client_socket(io_context);
acceptor.accept(client_socket); // Connect to the internal server (i.e., device inside the LAN)
tcp::resolver resolver(io_context);
tcp::resolver::results_type endpoints = resolver.resolve("localhost", "80");
tcp::socket server_socket(io_context);
boost::asio::connect(server_socket, endpoints); // Start tunneling data between client and server
tunnel_data(client_socket, server_socket); return 0;
}
三、总结
内网穿透技术通过各种手段使得外部设备能够访问位于内网中的服务。通过反向代理、TCP 隧道和 UDP 打洞等技术,我们可以根据不同的网络环境和需求,选择最合适的内网穿透方案。C++ 提供了高效的网络编程支持,可以用来实现这些方案中的每一种。
CPP在内网穿透技术的思考的更多相关文章
- [网络]NAT与内网穿透技术初探【待续】
1 局域网网段IP 要真正了解NAT就必须先了解现在IPv4地址的使用情况,私有 IP 地址是指内部网络或主机的IP 地址,公有IP 地址是指在因特网上全球唯一的IP 地址.RFC 1918 为私有网 ...
- 【新晋开源项目】内网穿透神器[中微子代理] 加入 Dromara 开源社区
1.关于作者 dromara开源组织成员,dromara/neutrino-proxy项目作者 名称:傲世孤尘.雨韵诗泽 名言: 扎根土壤,心向太阳.积蓄能量,绽放微光. 拘浊酒邀明月,借赤日暖苍穹. ...
- 手写内网穿透服务端客户端(NAT穿透)原理及实现
Hello,I'm Shendi. 这天心血来潮,决定做一个内网穿透的软件. 用过花生壳等软件的就知道内网穿透是个啥,干嘛用的了. 我们如果有服务器(比如tomcat),实际上我们在电脑上开启了服务器 ...
- QuantumTunnel:内网穿透服务设计
背景 最近工作中有公网访问内网服务的需求,便了解了内网穿透相关的知识.发现原理和实现都不复杂,遂产生了设计一个内网穿透的想法. 名字想好了,就叫QuantumTunnel,量子隧道,名字来源于量子纠缠 ...
- UDP广域网,局域网通信-原理分析,穿透技术
一.UDP局域网通信. 这个比较简单,关于局域网中的2台或者更多的计算机之间的UDP通信,网络上一大把,直接复制粘贴就可以使用,原理也非常简单.所以,本文不做详细介绍. 二.UDP广域通信(包括路由器 ...
- p2p穿透技术
ios 怎么和wifi外设摄像头实时传输视频 ios 控制wifi摄像头外设的拍照.录像.删除照片等等都可以通过tcp/ip 发送定义好的json指令实现. 但是不知道怎么和wifi外设摄像头实时传输 ...
- 记录一下自己总结出来的,在内网环境下使用maven打包的各种方法,包括各种常用的打包方式(一)
(一)内外网代理仓库搭建 想了一下,先用这个MAVEN安装部署的说明随笔,作为自己的第一篇技术帖,往后会陆陆续续将自己研究的心得发出来,留下脚印.希望有大神可以指点 一 .文章主要解决问题说明 1) ...
- frp内网 穿透映射使内网svn可外网访问
起因 公司svn目前部署在内网服务器上,现在想在家中也可以使用,因此需要外网访问内网的工具 经过 使用过几个产品: utools,一个小巧的windows下的工具,内网映射只是它的一个小功能,支持tc ...
- 在内网环境使用WPAD/PAC和JS攻击win10
转:https://mp.weixin.qq.com/s/qoEZE8lBbFZikKzRTwgdsw 在内网环境使用WPAD/PAC和JS攻击win10 2018-03-01 wangrin 看雪学 ...
- frp 内网穿透访问内网Web服务
ps:最近想要通过域名(公网)访问或者测试在本地搭建的 web 服务(不想在公网IP服务器上再部署个服务,也不想通过teamview等工具远程卡到爆!), 由于本地机器没有公网 IP,无法将域名解析到 ...
随机推荐
- 「悬浮捷径SoftCircle」安卓平台的hao123,一键打开万物
罗老师的onestep一步发布之前, 终端的打开形式还拘泥于桌面和负一屏 这种方式够简洁,但缺点明显: 1.入口单一性:只能在app首页和各种扫一扫之间选择和切换 2.操作复杂:入口切换需要频繁的进入 ...
- 类、事件与对象---Dad&Mom&Friends(进阶事件)
接上一个笔记:https://www.cnblogs.com/StephenYoung/p/17792668.html 现在增加了一个新的朋友类:Friends 这个类构造如下: 从上到下依次是: 1 ...
- 怒肝半月!Python 学习路线+资源大汇总
Python 学习路线 by 鱼皮. 原创不易,请勿抄袭,违者必究! 大家好,我是鱼皮,肝了十天左右的 Python 学习路线终于来了~ 和之前一样,在看路线前,建议大家先通过以下视频了解几个问题: ...
- vue --version 显示的却是vue cli的版本号,为什么?
vue --version 显示的却是vue cli的版本号,为什么? 如果您在运行 vue --version 命令时显示的是 Vue CLI 的版本号,而不是 Vue.js 的版本号,那可能是因为 ...
- ffmpeg精简
自:http://www.chinavideo.org/viewthread.php?tid=5567&extra=page%3D1&page=2 现在更新一下目前遇到的问题: 我想裁 ...
- mysql DCL常用命令
登录数据库: mysql -u root -p 查看本机MySQL中所有的用户 select user ,host from mysql.user; 查看所有数据库: show databases; ...
- 《最新出炉》系列初窥篇-Python+Playwright自动化测试-59 - 判断元素是否显示 - 上篇
1.简介 有些页面元素的生命周期如同流星一闪,昙花一现.我们也不知道这个元素在没在页面中出现过,为了捕获这一美好瞬间,让其成为永恒.我们就来判断元素是否显示出现过. 在操作元素之前,可以先判断元素的状 ...
- 【JDBC】Extra02 SqlServer-JDBC
官网驱动获取地址: https://www.microsoft.com/zh-cn/download/details.aspx Maven仓库获取: https://mvnrepository.com ...
- 2018年视频,路径规划:层次化路径规划系统——hierarchical pathfinding system —— Hierarchical Dynamic Pathfinding for Large Voxel Worlds (续)
前文: 2018年视频,路径规划:层次化路径规划系统--hierarchical pathfinding system -- Hierarchical Dynamic Pathfinding for ...
- 大语言模型(LLM)运行报错:module ‘streamlit‘ has no attribute ‘chat_message‘
参考: https://blog.csdn.net/weixin_45748921/article/details/134645308 问题在于版本不匹配,深究一下为什么各个版本软件不匹配,发现原因是 ...