内网穿透在实际生活中,我们经常会在内网里部署服务让外网访问内网应用,比如Apache,Tomcat,数据库,微信小程序的开发以及企业的一些管理软件(OA、CRM、ERP),还有远程桌面等等的外网都是无法直接访问内网的。

有些方式可以通过设置路由器虚拟服务器开放一些端口供外网访问,但由于运营商的原因,这些IP有时候并不是直接的IP,更多的时候这些IP都是动态的,简单说就是今天给你的IP是15.63.87.251,明天随时都有可能变为变得IP,并且是不能访问80个443端口的,那么有没有一种办法可以实现在没有公网IP的情况下,又不用设置路由器就可以让外网直接访问内网里的应用呢,今天要讲的就是这个:

首先普及一下基本的概念,可能有些拗口,不过没关系,这个看不懂也不要紧,可以直接跳过这一段:

什么是内网穿透、为什么要内网穿透,内网、公网和NAT是什么意思? 
公网、内网是两种Internet的接入方式。

内网接入方式:上网的计算机得到的IP地址是Inetnet上的保留地址,保留地址有如下3种形式:    
 10.x.x.x 
 172.16.x.x至172.31.x.x 
 192.168.x.x 
  内网的计算机以NAT(网络地址转换)协议,通过一个公共的网关访问Internet。内网的计算机可向Internet上的其他计算机发送连接请求,但Internet上其他的计算机无法向内网的计算机发送连接请求。

公网接入方式:上网的计算机得到的IP地址是Inetnet上的非保留地址。公网的计算机和Internet上的其他计算机可随意互相问。 
    NAT(Network Address Translator)是网络地址转换,它实现内网的IP地址与公网的地址之间的相互转换,将大量的内网IP地址转换为一个或少量的公网IP地址,减少对公网IP地址的占用。NAT的最典型应用是:在一个局域网内,只需要一台计算机连接上Internet,就可以利用NAT共享Internet连接,使局域网内其他计算机也可以上网。使用NAT协议,局域网内的计算机可以访问Internet上的计算机,但Internet上的计算机无法访问局域网内的计算机。
    Windows操作系统的Internet连接共享、sygate、winroute、unix/linux的natd等软件,都是使用NAT协议来共享Internet连接。 所有ISP(Internet服务提供商)提供的内网Internet接入方式,几乎都是基于 NAT协议的。

什么是固定IP、动态IP地址、什么是域名?
固定IP地址是长期分配给一台计算机或网络设备使用的IP地址。一般来说,采用专线上网的计算机才拥有固定的IP地址。

什么是动态IP地址 ?

通过Modem、ISDN、ADSL、有线宽频、小区宽频等方式上网的计算机,每次上网所分配到的IP地址都不相同,这就是动态IP地址。因为IP地址资源很宝贵,大部分用户都是通过动态IP地址上网的。普通人一般不需要去了解动态IP地址,这些都是计算机系统自动完成的。

当然在很多情况下你可能并没有公网IP,不要问我为什么,本人曾经做过2年的售后工程师,给几百家客户安装实施部署过软件,有3分之一的企业虽然有路由器,但运营商分给的IP却是内网的,奇怪吧,比如10、172或者100开头的都是运营商的内网IP。

这里简单说一下怎么查看是否是内网IP:
1.如果你使用的是Window平台,点击自己电脑窗口的“开始”“运行”输入“cmd”,在DOS命令窗口输入“ipconfig /all”,得到的IP如果和上面一样,说明你拥有自己的外网IP
2.如果你使用的是unix/linux平台,运行 ifconfig -a 得到的IP如果和上面一样,说明你拥有自己的外网IP。

现在开始正式进入正题:

接下来我就演示2个应用,一个是设置远程桌面,设置让外网可以通过3389远程控制局域网内的电脑,另一个就是访问内网里Tomcat的应用,端口是8080,使用的工具是神卓互联,快速实现内网穿透。
首先可以去神卓互联官网下载一个客户端。(地址自己百度吧),这个一般是针对企业级应用的,比如管家婆,OA系统等等,对于我们这些平民可以使用社区版,这个真的是免费的。
 

填写自己要穿透的应用名称和端口号,如果需要获取原访问者IP最好是选择Web应用。提交提交就可以了。

例如我需要发布一个Tomcat应用,访问端口号是7070,那么应用名称填写tomcat,内网主机填写127.0.0.1,内网端口填7070点提交就可以。

首先新建一个web项目

新建login.jsp登陆文件,内容如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录系统</title>
<style type="text/css">
table td{font: 14px/1.5 'Microsoft YaHei',arial,tahoma,\5b8b\4f53,sans-serif;}
</style>
</head>
<body>
<table>
<tr><td>用户名</td><td><input type="text"></td></tr>
<tr><td>密码</td><td><input type="text"></td></tr>
<tr><td>&nbsp;</td><td><input type="submit" value="登录"></td></tr>
</table>
</body>
</html>

先在本地运行,看项目是否可以正常运行

本地运行没有问题,可以正常打开,接下来就试一下外网访问

打开神卓互联软件主界面,右键选择外网访问

如果需要绑定域名访问的话也很简单,这里不多说。

接下来就分析是如何做到将请求转发到内网因为又返回给访问客户端的。

接下来就是java版的TCP打洞核心代码

由于32位Ip地址的稀少,我们身边的设备,大部分运行在nat后面,无论是家庭还是单位,都会由一个路由器统一接入互联网,很多设备连上路由器组成一个内网。同一内网里的所有设备,拥有相同的外网ip地址,内网设备对外网进行访问,每次会使用不同的端口进行通信,不同内网里面的设备不能直接进行连接 ,因为不知道对方的公网地址和端口,这个时候就需要借助一台公网的设备进行牵线搭桥,也就是大家常说的穿透打洞。穿透的原理和NAT的运行原理,就不在此讨论,网上已有大量理论文章。

假设现在有以下3台机器:

外网机器,IP:121.56.21.85 , 以下简称“主机A”

处在内网1下的机器,外网IP:106.116.5.45 ,内网IP:192.168.1.10, 以下简称“主机1”

处在内网2下的机器,外网IP:104.128.52.6 ,内网IP:192.168.0.11,以下简称“主机2”

很显然内网的两台机器不能直接连接,我们现在要实现的是借助外网机器,让两台内网机器进行tcp直连通讯。

实现过程如下:

1、主机A启动服务端程序,监听端口8888,接受TCP请求。

2、启动主机1的客户端程序,连接主机A的8888端口,建立TCP连接。

3、启动主机2的客户端程序,连接主机A的8888端口,建立TCP连接。

4、主机2发送一个命令告诉主机A,我要求与其他设备进行连接,请求协助进行穿透。

5、主机A接收到主机2的命令之后,会返回主机1的外网地址和端口给主机2,同时把主机2的外网地址和端口发送给主机1。

6、主机1和主机2在收到主机A的信息之后,同时异步发起对对方的连接。

7、在与对方发起连接之后,监听本地与主机A连接的端口(也可以在发起连接之前),(由于不同的操作系统对tcp的实现不尽相同,有的操作系统会在连接发送之后,把对方的连接当作是回应,即发出SYN之后,把对方发来的SYN当作是本次SYN的ACK,这种情况就不需要监听也可建立连接,本文的代码所在测试环境就不需要监听,测试环境为:服务器centos 7.3, 内网1 win10,内网2 win10和centos7.2都测试过)。

8、主机1和主机2成功连上,可以关闭主机A的服务,主机1和主机2的连接依然会持续生效,不关闭就形成了一个3方直连的拓扑网状结构网络。

服务器端代码:

package org.inchain.p2p;import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;/*** 外网端服务,穿透中继* * @author ln**/
public class Server {public static List<ServerThread> connections = new ArrayList<ServerThread>();public static void main(String[] args) {try {// 1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口ServerSocket serverSocket = new ServerSocket(8888);Socket socket = null;// 记录客户端的数量int count = 0;System.out.println("***服务器即将启动,等待客户端的连接***");// 循环监听等待客户端的连接while (true) {// 调用accept()方法开始监听,等待客户端的连接socket = serverSocket.accept();// 创建一个新的线程ServerThread serverThread = new ServerThread(socket);// 启动线程serverThread.start();connections.add(serverThread);count++;// 统计客户端的数量System.out.println("客户端的数量:" + count);}} catch (IOException e) {e.printStackTrace();}}
}
package org.inchain.p2p;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;/*** 外网端服务多线程处理内网端连接* * @author ln**/
public class ServerThread extends Thread {// 和本线程相关的Socketprivate Socket socket = null;private BufferedReader br = null;private PrintWriter pw = null;public ServerThread(Socket socket) throws IOException {this.socket = socket;this.br = new BufferedReader(new InputStreamReader(socket.getInputStream()));this.pw = new PrintWriter(socket.getOutputStream());}// 线程执行的操作,响应客户端的请求public void run() {InetAddress address = socket.getInetAddress();System.out.println("新连接,客户端的IP:" + address.getHostAddress() + " ,端口:" + socket.getPort());try {pw.write("已有客户端列表:" + Server.connections + "\n");// 获取输入流,并读取客户端信息String info = null;while ((info = br.readLine()) != null) {// 循环读取客户端的信息System.out.println("我是服务器,客户端说:" + info);if (info.startsWith("newConn_")) {//接收到穿透消息,通知目标节点String[] infos = info.split("_");//目标节点的外网ip地址String ip = infos[1];//目标节点的外网端口String port = infos[2];System.out.println("打洞到 " + ip + ":" + port);for (ServerThread server : Server.connections) {if (server.socket.getInetAddress().getHostAddress().equals(ip)&& server.socket.getPort() == Integer.parseInt(port)) {//发送命令通知目标节点进行穿透连接server.pw.write("autoConn_" + socket.getInetAddress().getHostAddress() + "_" + socket.getPort()+ "\n");server.pw.flush();break;}}} else {// 获取输出流,响应客户端的请求pw.write("欢迎您!" + info + "\n");// 调用flush()方法将缓冲输出pw.flush();}}} catch (Exception e) {e.printStackTrace();} finally {System.out.println("客户端关闭:" + address.getHostAddress() + " ,端口:" + socket.getPort());Server.connections.remove(this);// 关闭资源try {if (pw != null) {pw.close();}if (br != null) {br.close();}if (socket != null) {socket.close();}} catch (IOException e) {e.printStackTrace();}}}@Overridepublic String toString() {return "ServerThread [socket=" + socket + "]";}
}

这可能是目前最好用的p2p外网访问内网软件(免费内网穿透)相关推荐

  1. 穿透内网,连接动态ip,内网ip打洞-----p2p实现原理(转)

    源: 穿透内网,连接动态ip,内网ip打洞-----p2p实现原理 转载于:https://www.cnblogs.com/LittleTiger/p/10107849.html

  2. P2P通信原理与实现(C++),NAT,网络穿透原理

    1.简介 当今互联网到处存在着一些中间件(MIddleBoxes),如NAT和防火墙,导致两个(不在同一内网)中的客户端无法直接通信.这些问题即便是到了IPV6时代也会存在,因为即使不需要NAT,但还 ...

  3. 【技术篇】详解,网络穿透,P2P,打洞的核心原理丨NAT,穿透的原理丨实现网络穿透

    [技术篇]详解,网络穿透,P2P,打洞的核心原理丨NAT,穿透的原理丨实现网络穿透 那些你肯定不理解的技术,网络穿透,P2P,打洞的核心原理 1. NAT的原理 2. 穿透的原理 3. 实现网络穿透 ...

  4. 长芯微32位MCU LCM32F103C8T6可P2P替换STM32F103C8T6,无需改动软件直接替代

    高频电源广泛应用于各行各业的金属材料热加工.热处理.热装配及焊接.熔炼等工艺中.它不但可以对工件整体加热,还能对工件局部的针对性加热:可实现工件的深层透热,也可只对其表面.表层集中加热:不但可对金属材 ...

  5. 金融爬虫python网贷_爬虫之爬取网贷之家在档P2P平台基本数据并存入数据库

    python 版本 :3.5.2 Jupyter Notebook 使用库: reuqests (For human) json (用来加载JSON数据) datetime (用来记录抓取所花时间,也 ...

  6. java p2p文件传输_P2P文件传输软件的设计与实现

    摘要:本系统是在深入了解P2P技术和JAVA实现平台的基础上,设计实现的基于JAVA的P2P文件传输软件,在局域网内实现点对点的文件传输功能.本系统的优点是在一个网络内每个Windows平台的客户机只 ...

  7. 没有公网IP,怎样远程查看视频监控?

    视频监控通常被称作"第三只眼".如今,除了最基础的安防需求外,视频监控在不同的应用场景延伸出了各种各样的功能需求,并且正与日俱增. 常见的家庭应用场景,如照看老人小孩.宠物等:常见 ...

  8. 因特网MySQL服务器_因特网服务器的主要功能

    <计算机网络:自顶向下方法(原书第6版)>一2.4 因特网中的电子邮件 本节书摘来华章计算机<计算机网络:自顶向下方法(原书第6版)>一书中的第2章 ,第2.4节,(美)Jam ...

  9. 360搜索官网认证说明

    官网简介 360官网认证,是当网民通过360搜索特定搜索词时,由用户提交,所触发的自然搜索结果中,对"该搜索词与所属主体唯一且对应一致的官方网站"展示官网标识,以防止山寨.钓鱼网站 ...

  10. Ubuntu常用软件大全(国内用户比较常用的软件)

    输入法平台 每个输入法平台都能加装很多种类输入法(如二笔.五笔.拼音) ibus 官网 (K)Ubuntu9.10之后预设输入法平台,为取代停滞的scim创造 fcitx 官网 小企鹅输入法平台 sc ...

最新文章

  1. Hadoop葵花宝典(一)
  2. 淘宝|蚂蚁|菜鸟|盒马|嘀嘀|饿了么面经(已拿多个offer)
  3. 一个应用在多视图光度立体视觉MVPS的NeRF方法
  4. 微型计算机分析,微机原理练习题分析
  5. Hibernate中1+N问题以及解决方法
  6. Redis1 晨考题
  7. w10恢复出厂设置_路由器如何恢复出厂设置
  8. ❤️《IOC理论推导》
  9. Linux 用户及权限详解
  10. Android Multimedia框架总结(二十一)MediaCodec中创建到start过程(到jni部分)
  11. atitit.印度教与java宗教的特点与观念对比 attilax总结
  12. word三线格模版绘制
  13. 天正暖通2013版安装包附带注册机下载
  14. 【基础系列】赏析刘洪普《PyTorch深度学习实践》与《实战:基于CNN的MNIST手写数字识别》(Python版)
  15. 2010年上半年5月份系统分析师上午试题答案(分析与解答)之十
  16. 萤石视频监控模式的参数decoderPath配置问题
  17. 数据结构学习笔记——栈(1)定义理解
  18. POJ1007 DNA Sorting中英对照翻译与参考解答
  19. cartographer_pose_extrapolator
  20. android换肤动画,Android换肤(二) — 插件式换肤

热门文章

  1. 2017年5月—信息安全工程师—上午综合知识(11-15)
  2. IT行业常见职位英语缩写及中文释义
  3. 《2022年中国网络安全市场全景图》
  4. 开源项目推荐:office办公软件,绘图软件
  5. html 右边是iframe 左右结构_HTML iframe 用法总结收藏
  6. android支持u盘格式文件,安卓系统OTG支持U盘格式
  7. 建模的计算机基础理论,数学建模基础理论
  8. 联想Lenovo手机平板安装谷歌服务框架Google, Play商店,安装套件GMS
  9. IPV6的福音---六维空间
  10. qomo linux最新版本,Qomo Linux下一个版本将推驱动中心