![](https://iknow-base.cdn.bcebos.com/lxb/notice.png)
外网如何访问内网服务器?
如何实现外网访问内网?路由器如何配置?
老板想在家里实现远程访问服务器,公司服务器IP192.168.1.8 DNS:192.168.1.8 展开
2019-05-06
由于运营商的原因,这些IP有时候并不是直接的IP,更多的时候这些IP都是动态的,简单说就是今天给你的IP是15.63.87.251,明天随时都有可能变为变得IP,并且是不能访问80个443端口的,那么有没有一种办法可以实现在没有公网IP的情况下,又不用设置路由器就可以让外网直接访问内网里的应用
首先可以去神卓互联下载一个客户端。这里演示一下外网远程访问内网里的服务器,下载好之后点安装就可以,没有其他多余的操作,
安装的过程很顺利,直接点下一步就可以了。
安装完成后我们就可以打开登录了,(这个登录框背景是半透明的,不要找不到/捂脸)
接下来就可以开始正式使用了。
接下来就是添加映射了,首先是3389远程访问的映射
点击主面板左下角的添加映射按钮
应用名称可以随便填,这里可以填远程桌面,服务器IP可以是局域网内任意IP,这里填写127.0.0.1就可以了,端口号肯定是填3389了,点击其二添加就好了。主面板就会返回一个固定的公网地址和端口号,当然这个地址可以把后面的端口号去掉,接下来就可以通过外网访问了,打开下面这个远程桌面连接,
点连接就可以远程访问内网里的应用了,码了这么多字希望可以帮到你
如果是开发运维人员可以参考下面的核心代码自己编写一个内网穿透软件。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Scanner;
/**
* 内网客户端,要进行穿透的内网服务
*
* @author ln
*
*/
public class Client {
//输入scanner
private Scanner scanner = new Scanner(System.in);
//是否等待输入
private boolean isWaitInput = true;
//首次与外网主机通信的连接
private Socket socket;
//首次与外网主机通信的本地端口
private int localPort;
private PrintWriter pw;
private BufferedReader br;
public static void main(String[] args) {
new Client().start();
}
public void start() {
try {
// 新建一个socket通道
socket = new Socket();
// 设置reuseAddress为true
socket.setReuseAddress(true);
//TODO在此输入外网地址和端口
String ip = "xxx.xxxx.xxxx.xxxx";
int port = 8888;
socket.connect(new InetSocketAddress(ip, port));
//首次与外网服务器通信的端口
//这就意味着我们内网服务要与其他内网主机通信,就可以利用这个通道
localPort = socket.getLocalPort();
System.out.println("本地端口:" + localPort);
System.out.println("请输入命令 notwait等待穿透,或者输入conn进行穿透");
pw = new PrintWriter(socket.getOutputStream());
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
try {
while (true) {
if(process()) {
break;
}
}
} finally {
// 关闭资源
try {
if(pw != null) {
pw.close();
}
if (br != null) {
br.close();
}
if (socket != null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* 处理与服务器连接的交互,返回是否退出
*/
private boolean process() throws IOException {
String in = null;
if (isWaitInput) {
//把输入的命令发往服务端
in = scanner.next();
pw.write(in + "\n");
//调用flush()方法将缓冲输出
pw.flush();
if ("notwait".equals(in)) {
isWaitInput = false;
}
}
//获取服务器的响应信息
String info = br.readLine();
if(info != null) {
System.out.println("我是客户端,服务器说:" + info);
}
//处理本地命令
processLocalCommand(in);
//处理服务器命令
processRemoteCommand(info);
return "exit".equals(in);
}
private void processRemoteCommand(String info) throws IOException {
if (info != null && info.startsWith("autoConn_")) {
System.out.println("服务器端返回的打洞命令,自动连接目标");
String[] infos = info.split("_");
//目标外网地址
String ip = infos[1];
//目标外网端口
String port = infos[2];
doPenetration(ip, Integer.parseInt(port));
}
}
private void processLocalCommand(String in) throws IOException {
if ("conn".equals(in)) {
System.out.println("请输入要连接的目标外网ip:");
String ip = scanner.next();
System.out.println("请输入要连接的目标外网端口:");
int port = scanner.nextInt();
pw.write("newConn_" + ip + "_" + port + "\n");
pw.flush();
doPenetration(ip, port);
isWaitInput = false;
}
}
/*
* 对目标服务器进行穿透
*/
private void doPenetration(String ip, int port) {
try {
//异步对目标发起连接
new Thread() {
public void run() {
try {
Socket newsocket = new Socket();
newsocket.setReuseAddress(true);
newsocket.bind(new InetSocketAddress(
InetAddress.getLocalHost().getHostAddress(), localPort));
System.out.println("connect to " + new InetSocketAddress(ip, port));
newsocket.connect(new InetSocketAddress(ip, port));
System.out.println("connect success");
BufferedReader b = new BufferedReader(
new InputStreamReader(newsocket.getInputStream()));
PrintWriter p = new PrintWriter(newsocket.getOutputStream());
while (true) {
p.write("hello " + System.currentTimeMillis() + "\n");
p.flush();
String message = b.readLine();
System.out.println(message);
pw.write(message + "\n");
pw.flush();
if("exit".equals(message)) {
break;
}
Thread.sleep(1000l);
}
b.close();
p.close();
newsocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
// //监听本地端口
// ServerSocket serverSocket = new ServerSocket();
// serverSocket.setReuseAddress(true);
// serverSocket.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), localPort));
//
// // 记录客户端的数量
// System.out.println("******开始监听端口:" + localPort);
// // 循环监听等待客户端的连接
// // 调用accept()方法开始监听,等待客户端的连接
// Socket st = serverSocket.accept();
//
// System.out.println("成功了,哈哈,新的连接:" + st.getInetAddress().getHostAddress() + ":" + st.getPort());
//
// serverSocket.close();
} catch (Exception e) {
e.printStackTrace();
System.out.println("监听端口 " + socket.getLocalPort() + " 出错");
}
}
内网主机穿透时一定要异步发起连接。