Java实现内网穿透

这篇具有很好参考价值的文章主要介绍了Java实现内网穿透。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

使用场景

1、当公司的一些系统功能使用了第三方服务时,通常第三方会回调我们的接口。在对接阶段,为了方便debug,我们肯定希望能回调到我们本地电脑上来。

2、当你在公司想访问部署在家里电脑的服务或者文件时。

3、当你的外地同事想访问你本地的服务,虽然发布到测试也可以,但是部署需要时间,发生错误排除也没有本地来的快,不够所见即所得。

虽然有现成的内网穿透工具,但没有比自己写的用起来更有成就感,哈哈哈哈~

而且自己写的,会遇到很多关于网络、线程的问题,网络的阻塞(代码跑着跑着就阻塞住了,也不知道为什么阻塞住了、阻塞在哪了,令人头大)、线程之间的配合(线程之间配合不好,导致数据在传输的时候缺少了,令人摸不着头脑),体会过一遍之后,更能加深自己对这方面知识了解,用这种有实际开发场景的学习方式,比直接背八股文效果更好,了解的更深(知其然,之所以然)。因为是体验、理解过这个知识点所带来的实际成果,能记忆的更深更久,不会像八股文背了又忘,忘了又背。

原理

其实很简单,外网服务器是不可能主动与内网服务器建立连接去通讯的,但是内网服务器可以,所以只要内网服务器告诉外网服务器“我”在哪里,那外网服务器就可以把请求的数据发送给内网服务器。

但是外网有这么多服务器,内网服务器要告诉哪个呢?总不能告诉全部服务器吧,不现实。所以,还是需要一台外网服务器跟内网服务器配合,内网服务器只告诉这个特定外网服务器“我”在哪,其他外网服务器或者内网服务器想要访问我的内网服务器,那就去访问特定外网服务器就可以了,特定外网服务器知道内网服务器在哪里,就可以转发相应的数据。

这个特定外网服务器就相等于代理服务器,转发外网和内网的数据,在它们中间建立了一座桥梁。

Java实现内网穿透

 Java实现内网穿透

在云厂商买一台服务器,因为有外网ip,再用Java写一个数据转发的进程就能实现特定服务器的功能,不过本地也是可以测试的,只要用不同的端口,有点像端口的流量转发。

加入了Server-Proxy跟Client-Proxy之后,就能访问内网的服务了。

Client-Proxy的作用:Client-Proxy上线之后告诉Server-Proxy“我”在哪,接收到Server-Proxy的数据之后会转发给本地的服务器,同时也会把本地服务器的数据转发给Server-Proxy。

Server-Proxy的作用:监听两个端口,一个用作外部服务的端口,一个用作监听Client-Proxy上线和数据传输的端口,也是用于数据的传输和回写。

Server-Proxy跟Client-Proxy中间建立的通道,是Client-Proxy上线之后主动与Server-Proxy建立的TCP长连接(图中红色的线,即客户端告诉服务端“我”在哪)。

Java代码实现

第一版

首先先实现一个最简单能跑通的模型,使用BIO,然后只支持一个Client-Proxy、外网Server的连接,因为tcp长连接只有一条,同时连入多个Socket要处理线程安全问题。第一版,主要先把上面的原理实现,具体实用性、性能先不管。

Java实现内网穿透

代码

src/main/java/com/lkz/intranetpenetration/base · master · qq_41084438 / Intranet penetration · GitCode

代码结构

Java实现内网穿透

执行流程

OuterNetSocketServer

当收到外网的请求之后,把流交给IntranetSocketServer

Java实现内网穿透

IntranetSocketServer

把外网的数据通过长连接写给Client-Proxy,在类实例化的时候已经开启了一条新线程IntraToOutThread,把内网的数据写给外网,两条线程同时进行。

Java实现内网穿透

Java实现内网穿透

ClientProxy

同理,同时处理数据的读和写。

Java实现内网穿透

Java实现内网穿透

 效果

在本地8080端口启动了SpringBoot服务,通过访问Server-Proxy的7777端口,调用到了8080端口的服务接口。

Server-Proxy

Java实现内网穿透

Client-Proxy

Java实现内网穿透

Outer-Server

Java实现内网穿透

 Intra-Server

Java实现内网穿透

第二版

背景

这一版主要想解决可以连入多个OuterServer的问题,因为我们代理转发的是Tcp,所以理论上所有使用了Tcp传输的服务我们都可以代理。

然后我尝试了一下Navicat连到我的Server-Proxy,Client-Proxy连到Mysql,是可以的。但是第一版代码是按照Http调试的,有点不适用。因为Http服务都是一问一答,客户端先发request,服务端返回response。而mysql不是,连上mysql之后,mysql会先发信息询问账号密码,客户端再回答。而且因为一些编码的问题,读写socket数据的时候需要用inputstream和outstream,不要把流再进行包装,否则会因为这个问题导致包错误。

主要是改ClientProxy代码。

Java实现内网穿透

 完整代码:src/main/java/com/lkz/intranetpenetration/mysql · master · qq_41084438 / Intranet penetration · GitCode

虽然能连接上Mysql,也其次而已。因为如果要打开数据库的话,Navicat会再新建一个Socket与Server-Proxy进行连接,这时就无响应了。

所以为了解决这个问题,把Server-Proxy升级成可以连接多个OuterServer。

Java实现内网穿透

 把模型升级成Server-Proxy与Client-Proxy有多条长连接,Server-Proxy能接收多个OuterServer的socket。这四者之间的连接是一一对应的,这样做的原因是简单高效,如果中间的Server-Proxy与Client-Proxy通道复用的话,会很复杂,同一时间通道不能同时读写,就要处理多线程问题。

这个模型还多了一条命令通道,用来命令Client-Proxy主动与Server-Proxy建立连接。每来一个OuterServer就需要在Client-Proxy与Server-Proxy之间建立一条长连接,因为这条连接不能由Server-Proxy来主动创建,所以通过命令的方式来控制Client-Proxy。

代码

src/main/java/com/lkz/intranetpenetration/multitcp · master · qq_41084438 / Intranet penetration · GitCode

代码结构

Java实现内网穿透

代码改动也不太,Server-Proxy把外网数据传输给内网的时候,需要同步发一条创建Tcp给Client-Proxy,等Tcp创建完成之后再开始发数据。Client-Proxy增加命令响应的代码。

唯一的小难点是,Server-Proxy通过命令通道创建了一条新的Tcp连接,发送创建命令和新建Tcp连接是在两个线程上进行的,怎么对应起来,把这条新的Tcp连接分配给OuterServer呢?

我的做法是,Server-Proxy发送创建Tcp命令并阻塞等待Client-Proxy响应,Client-Proxy收到命令与Server-Proxy建立新的Tcp连接,连接建立完成,Server-Proxy往这条新连接发送一个id,Client-Proxy收到这个id再发送给等待Client-Proxy响应的那条线程。

IntranetSocketServer

Java实现内网穿透

CMDSocketServer

Java实现内网穿透

ClientProxy

Java实现内网穿透

 效果

用navicat连到Server-Proxy的端口。

Server-Proxy

Java实现内网穿透

Client-Proxy

Java实现内网穿透

未来改进

到这里,自己拿来用基本没什么问题了,不过优化的点还是有很多的,后续再继续优化。

1、复用Server-Proxy与Client-Proxy之间的连接,第二版中,这条连接需要频繁的创建和销毁,开销很大,如果能有类似Tcp池的东西去管理,就能减少很多开销。

2、上面第一点也可以这样优化,给外网的几个socket分配一条Tcp长连接,就不是一个socket对应一条长连接了,这样Tcp通道的利用率会更高,同时也更难实现,因为要处理多线程并发写同一条Tcp的问题,控制不好反而性能下降或者造成数据错乱。

Java实现内网穿透

3、为Client-Proxy实现一个界面(Java GUI)。

4、支持多个Client-Proxy连入,根据不同的规则,把流量转发到不同的Client-Proxy。

5、引入规则的配置,让Client-Proxy可以代理到多个本地服务端口。

6、实现心跳机制。

7、BIO网络模型改为NIO模型。

8、流量的监控、Tcp连接监控、流量的速度控制、动态修改配置(超时读、Tcp长连接数量)、手动下线客户端、客户端黑名单。

项目代码:文件 · master · qq_41084438 / Intranet penetration · GitCode文章来源地址https://www.toymoban.com/news/detail-416089.html

到了这里,关于Java实现内网穿透的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 如何在Ubuntu系统使用Docker搭建MongoDB结合内网穿透实现公网连接

    本文主要介绍如何在Linux Ubuntu系统使用Docker快速部署MongoDB,并结合cpolar内网穿透工具实现公网远程访问本地数据库。 MongoDB服务端可以运行在Linux、Windows、MacOS平台,可以存储比较复杂的数据类型,支持的查询语言非常强大,几乎可以实现类似关系数据库单表查询的绝大部分

    2024年03月26日
    浏览(48)
  • 如何在Linux系统使用docker部署Apache Superset并结合内网穿透实现公网远程访问

    Superset是一款由中国知名科技公司开源的“现代化的企业级BI(商业智能)Web应用程序”,其通过创建和分享dashboard,为数据分析提供了轻量级的数据查询和可视化方案。Superset在数据处理和可视化方面具有强大的功能,能够满足企业级的数据分析需求,并为用户提供直观、灵

    2024年03月13日
    浏览(50)
  • 内网穿透的应用-使用Docker搭建一个Wiki.Js知识库系统并实现分享他人远程创作

    不管是在企业中还是在自己的个人知识整理上,我们都需要通过某种方式来有条理的组织相应的知识架构,那么一个好的知识整理工具是非常重要的,今天推荐一款维基知识库系统——Wiki.js。 本文将介绍如何用 Docker 容器技术部署 Wiki.js 应用程序,并且结合cpolar发布至公网实

    2024年01月18日
    浏览(37)
  • Java实现内网穿透

    1、当公司的一些系统功能使用了第三方服务时,通常第三方会回调我们的接口。在对接阶段,为了方便debug,我们肯定希望能回调到我们本地电脑上来。 2、当你在公司想访问部署在家里电脑的服务或者文件时。 3、当你的外地同事想访问你本地的服务,虽然发布到测试也可以

    2023年04月17日
    浏览(12)
  • 常见的一些内网穿透工具

    内网穿透的英文叫做 NAT traversal,又被称为端口映射或内网映射,内网穿透是网络连接术语,即在计算机是局域网内的时候,外网与内网的计算机的节点进行连接时所需要的连接通信,有时候就会出现内网穿透不支的情况。 内网穿透的功能就是,当我们在端口映射时设置时,

    2024年02月06日
    浏览(23)
  • 使用Apache和内网穿透实现私有服务公网远程访问——“cpolar内网穿透”

    Apache作为全球使用较高的Web服务器软件,它可以在几乎所有常见的计算机平台上运行。由于其卓越的跨平台性和高级安全性,又兼具快速、可靠且易于通过简单的API扩展而闻名,被广泛应用于Web服务器领域。本文主要分享一下在Windows系统如何安装与配置Apache服务,并结合内网

    2024年02月08日
    浏览(38)
  • 内网穿透实战应用-windwos10系统搭建我的世界服务器,内网穿透实现联机游戏Minecraft

    今天和大家分享一下只需简单几步即可在windwos系统搭建我的世界服务器,并通过cpolar内网穿透工具将本地服务暴露到公网连接,实现与小伙伴一起联机游戏。 以windows10系统为例,配置java环境,搭建我的世界服务器,下载最新版java版本 https://www.oracle.com/java/technologies/downloads/

    2024年02月11日
    浏览(40)
  • 【内网穿透】Linux服务使用宝塔面板搭建网站,并内网穿透实现公网远程访问

    转载自cpolar极点云文章:Linux使用宝塔面板搭建网站,并内网穿透实现公网访问 宝塔面板作为简单好用的服务器运维管理面板,它支持Linux/Windows系统,我们可用它来一键配置LAMP/LNMP环境、网站、数据库、FTP等,通过Web端轻松管理服务器。 以下教程,我们将演示使用宝塔面板

    2024年02月12日
    浏览(37)
  • 使用frp实现内网穿透

    本篇博客最早发布于实验室公共博客,但已无人维护,现迁移至个人博客 一打五师兄走之前留了一块树莓派给我,暑假闲来无事拿出来玩玩 如果每次都连接显示屏和键盘使用有点麻烦而且低级 正常笔记本和树莓派都连着实验室的WIFI,网段一样,是可以ssh远程登录的 但我突

    2024年02月09日
    浏览(29)
  • 使用nps实现内网穿透

    ​ 当我们想把内网的一些资源暴露在公网上时,可以使用内网穿透功能。比如公司的内网服务器,部署了平时需要开发的项目,但是回到家中无法访问,就可以使用内网穿透,将公司内网的接口映射到一台公网的服务器上,用这台公网服务器做转发即可实现在家中也能外网访

    2024年02月11日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包