首页 > 编程语言 >内网穿透技术的思考--反向代理、TCP 隧道、 UDP 打洞--C++代码示例

内网穿透技术的思考--反向代理、TCP 隧道、 UDP 打洞--C++代码示例

时间:2024-09-14 09:52:35浏览次数:10  
标签:asio UDP socket io 示例 -- tcp context boost

概述

内网穿透是一种技术,用于在私有局域网(LAN)中的设备与外部网络(如互联网)之间建立通信通道,使得外部设备可以访问内网中的服务。由于内网设备通常位于防火墙或 NAT(网络地址转换)设备之后,外部网络无法直接访问它们。因此,内网穿透技术旨在解决这一问题。本文将讨论如何使用 C++ 实现内网穿透技术,并介绍一些常见的实现方式。

一、内网穿透的基本原理

内网穿透的核心思想是通过一个中间服务器(通常位于公网中)来中转内网的请求。内网设备与外网设备通过这个中间服务器进行通信,避开防火墙或 NAT 设备的限制。具体流程包括以下步骤:

  1. 内网设备主动连接到中间服务器:由于 NAT 设备允许内部设备主动发起外部连接,因此内网设备可以与位于公网的中间服务器建立连接。
  2. 外网设备向中间服务器发出请求:外网设备通过公网 IP 地址访问中间服务器,请求访问内网中的服务。
  3. 中间服务器转发请求:中间服务器将外网设备的请求转发给已经连接的内网设备,内网设备响应后再通过中间服务器返回给外网设备。

二、常见的内网穿透技术实现手段

  1. 反向代理(Reverse Proxy) 反向代理是一种常见的内网穿透方式。使用反向代理时,内网设备主动与中间服务器建立连接,并保持连接的持续性。外网设备通过访问中间服务器获取内网服务。

    • 实现思路
      • 使用 C++ 开发的客户端程序在内网设备上运行,主动连接位于公网的中间服务器(该服务器可以使用 C++ 通过 socket 实现)。
      • 中间服务器充当代理,将外网的请求通过内网设备返回。
    • C++ 示例: 下面展示了一个简单的反向代理服务器的基本结构:   ?
      1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #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; }

        

  2. TCP 隧道(TCP Tunneling) TCP 隧道是一种通过中间服务器将外网请求直接转发到内网设备的方法。外网设备与内网设备之间的数据流通过中间服务器进行封装和转发,内网设备将其解封装后处理请求。

    • 实现思路

      • 使用 C++ 实现 TCP 隧道的功能,内网设备和外网设备同时与中间服务器保持连接。
      • 外网设备发送请求时,中间服务器将数据包转发给内网设备处理。
    • C++ 示例

        ?
      1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #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; }

        

  3. UDP 打洞(UDP Hole Punching) UDP 打洞是一种广泛使用于 P2P 网络的技术。该技术通过让两个处于不同 NAT 后面的设备同时向一个中间服务器发送 UDP 数据包,从而建立起两者之间的直接通信。

    • 实现思路

      • 使用 C++ 开发内网设备的 UDP 客户端,同时向中间服务器和目标设备发送数据包。
      • 中间服务器在收到来自两个设备的请求后,向双方告知彼此的公网 IP 和端口号,进而双方可以通过该信息直接进行通信。
    • C++ 示例

        ?
      1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #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++ 提供了高效的网络编程支持,可以用来实现这些方案中的每一种。

 

2024-09-14 09:48:38【出处】:https://www.cnblogs.com/thinkingmore/p/18412083

=======================================================================================

标签:asio,UDP,socket,io,示例,--,tcp,context,boost
From: https://www.cnblogs.com/mq0036/p/18413369

相关文章

  • 【Fellow 领衔 | 高校认可会议 | 高录用 | EI检索 | 大会报告 | 人工智能、计算机、图
    重要信息大会网站:https://ais.cn/u/UFFvEb【投稿参会】截稿时间:以官网信息为准大会时间:2024年11月8-10日大会地点:中国-南京提交检索:EICompendex、Scopus*现场可领取会议资料(如纪念品、参会证书等),【click】投稿优惠、优先审核!支持单位:征稿主题智能信息检索技......
  • 当代码遇上“意外”:Python中的异常引发艺术
    引言异常处理是软件开发不可或缺的一部分。良好的异常管理不仅能够提升程序的稳定性与可靠性,还能显著改善用户体验。在Python中,“异常的引发”是指主动抛出一个错误信息,以通知调用者当前操作出现了问题。掌握这一技巧,对于编写高效、可维护的代码至关重要。基础语法介绍在Python......
  • verilog-1| 仲裁器
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档目录前言一、固定优先级仲裁器(FixedPriorityArbiter)1、case/if语句实现2、for循环语句实现参数化3、展开for循环的变体 4、补码相与法二、轮询仲裁器(RoundRobinArbiter)1、优先级仲裁器+优先级......
  • Python 入门教程(3)基础知识 | 3.2、数据类型、变量与常量
    文章目录一、数据类型、变量与常量1、数据类型2、变量3、常量一、数据类型、变量与常量1、数据类型Python的数据类型可以分为不可变类型和可变类型。不可变类型包括整数、浮点数、布尔值和元组,一旦创建,其值就不能改变。可变类型包括列表、字典和集合,它们的值可以......
  • JWT在分布式架构中的应用实践|使用Java构建安全的身份验证系统|使用Java构建安全的身份
    JWT(JSONWebToken)是一种基于JSON的开放标准,用于在双方之间安全地传输信息。JWT因其轻量级、安全性和跨平台特性,在现代Web应用中被广泛使用。通过JWT,可以方便地进行用户身份验证、信息传递等场景。然而,对于开发者来说,如何正确解析JWT以验证其合法性和提取其中的信息至关重要。在这......
  • Datadog 监控最佳实践 | 收集正确的数据
    本文是Datadog“高效监控”系列的第一篇,后面还会有第二篇《针对重要事项发出警报》和《调查性能问题》。监控数据有多种形式-一些系统不断地输出数据,而另一些系统仅在罕见事件发生时才产生数据。有些数据主要用于识别发现问题、有些数据主要用于调查问题。更宽泛地说,监控数据是......
  • 【北京语言大学主办 | 快速见刊 | 高校认可会议 | 人文社科年度重磅会议 | 往届已见刊
    重要信息大会网站:https://ais.cn/u/zYJRZj【投稿参会】截稿时间:以官网信息为准大会时间:2024年11月22-24日大会地点:中国-北京主办单位:北京语言大学提交检索:CPCI、CNKI(知网)、GoogleScholar(谷歌学术) ↑快速检索↑见刊出版:会议论文集出版(快见刊)*含online线上见刊链......
  • 哈莫尼斯 手工王国 Harmonis the hand made kingdoms,官方中文,解压即玩,
    游戏截图 哈莫尼斯手工王国HarmonisthehandmadekingdomsHarmonis:手工王国是一款极简策略游戏,让您的创造力成为中心舞台。通过独特的瓷砖塑造生机勃勃的王国,每一块瓷砖都为一个充满活力和动态的世界做出贡献。从郁郁葱葱的森林到干旱的沙漠,探索各种生物群落,并在您......
  • 20240909_151725 c语言 整数扩展
    完整形态类型后根int有无符号unsigned%u使用%u会约束输出无符号数据。如果是一个负数就会显示出错。使用%d可正常显示数据整数小结......
  • JS中判断数据类型的四种方法
    前言近期回顾了JS的知识,重新梳理一下几种不同的判断数据类型的方式,对于不同的数据类型,可以用不同的判断方式,防止类型判断的不够精确。一.typeoftypeof可以用来判断number、string、boolean、undefined这四种简单数据类型,以及function这个引用类型(复杂数据类型)。具体写法如下:type......