没有固定IP搭建服务器

一个近乎完美的解决方案

背景:需要一台20兆左右宽带的服务器,但是阿里云的云服务器太贵,如果带宽高的话,就更贵了。但是直接用本地的服务器,没有企业的公网固定ip,只有动态公网IP,只能ddns解决,但是ddns非企业的ttl时长最短也需要10分钟,ttl就是域名解析结果(ip地址)在运营商dns上保存的时长。如果这更新后的10分钟有用户通过域名访问,就会被运营商的dns导向一个不存在服务器的ip地址。真实ip无法及时更新。访问不到服务器。

没有企业,因此需要一个廉价的解决方案

↓↓↓

需要准备:阿里云ecs实例一个(勾选阿里云分配公网ip),本地网络是公网ip,阿里云域名一个(方便后续升级,防止解析服务器ip变化,用来解析aliyunecs,没有的话用阿里云ecs的ip直接访问也行,但是不安全)

实现方法:在本地服务器搭建真正的数据库,所有的东西都运行在本地服务器,再额外编写一个获取本机ip的程序,并通过ajax上传到阿里云,每隔1秒检测一次,如果变化,就上传到阿里云ecs。

1-1.实时获取本机IP并打印在浏览器页面的方法(JavaScript需要浏览器打开webrtc)

<!DOCTYPE html>

<html>

<head>

</head>

<body>

    <h1>实时本机IP地址</h1>

    <p id="ip"></p >



    <script>

        function getLocalIP(callback) {

            const RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection || window.mozRTCPeerConnection;

            const rtc = new RTCPeerConnection({iceServers: []});

            const noop = function(){};

            

            rtc.createDataChannel('');



            rtc.createOffer(function(sessionDescription) {

                rtc.setLocalDescription(sessionDescription, noop, noop);

            }, noop);



            rtc.onicecandidate = function(event) {

                if (event.candidate) {

                    const ipRegex = /\b(?:\d{1,3}\.){3}\d{1,3}\b/;

                    const match = ipRegex.exec(event.candidate.candidate);

                    const localIP = match ? match[0] : 'unknown';

                    callback(localIP);

                    rtc.onicecandidate = noop;

                }

            };

        }



        setInterval(function() {

            getLocalIP(function(localIP) {

                document.getElementById("ip").innerHTML = "Local IP Address: " + localIP;

            });

        }, 1000); // 更新频率(以毫秒为单位)



    </script>

</body>

</html>

1-2.实时获取本地IP并上传(JavaScript+html实现)

//以下是使用普通JavaScript实现的前端代码示例,与下述Java服务器进行交互并存储和替换字符串:

html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>String Storage Client</title>
</head>
<body>
    <h1>String Storage Client</h1>
    
    <div id="status"></div>
    
    <label for="password">Access Password:</label>
    <input type="password" id="password">
    
    <br>
    
    <label for="newString">New String:</label>
    <input type="text" id="newString">
    
    <br><br>
    
    <button onclick="getStoreString()">Get Stored String</button>
    
    <br><br>
    
    <button onclick="updateString()">Update String</button>
    
    <script>
        const serverUrl = "http://localhost:8080";
        
        function sendHttpRequest(url, method, data, successCallback, errorCallback) {
            const xhr = new XMLHttpRequest();
            xhr.open(method, url);
            xhr.onreadystatechange = function() {
                if (xhr.readyState === XMLHttpRequest.DONE) {
                    if (xhr.status === 200) {
                        successCallback(xhr.responseText);
                    } else {
                        errorCallback(xhr.responseText);
                    }
                }
            };
            xhr.send(data);
        }
        
        function getStoreString() {
            const password = document.getElementById("password").value;
            
            sendHttpRequest(serverUrl, "POST", password, function(response) {
                document.getElementById("status").textContent = "Stored String: " + response;
            }, function(error) {
                document.getElementById("status").textContent = "Error: " + error;
            });
        }
        
        function updateString() {
            const password = document.getElementById("password").value;
            const newString = document.getElementById("newString").value;
            
            const requestData = password + "\n" + newString;

            sendHttpRequest(serverUrl, "POST", requestData, function(response) {
                document.getElementById("status").textContent = "Update Successful: " + response;
            }, function(error) {
                document.getElementById("status").textContent = "Error: " + error;
            });
        }
    </script>
</body>
</html>

//这个前端代码使用了普通的JavaScript来发送XMLHttpRequest请求与
//服务器进行交互。页面中有两个输入框,一个用于输入访问密码,另
//一个用于输入新的字符串。点击"Get Stored String"按钮将发送密码
//给服务器进行校验,并将服务器返回的存储的字符串显示在页面上。
//点击"Update String"按钮将同时发送密码和新字符串给服务器,用于替换服务器中存储的字符串。

//请确保将`serverUrl`变量根据实际服务器的地址进行修改,以确保与Java服务器的URL地址匹配。

1-3云服务器端监听真实服务器发来的真实IP(Java实现)

以下是一个使用Java编写的示例服务器,可以存储前端发来的字符串并校验访问密码,以后前端再发送该字符串,就替换服务器里存储的这个字符串:

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.PrintWriter;

import java.net.ServerSocket;

import java.net.Socket;



public class StringStorageServer {

    private static final int PORT = 8080;

    private static final String ACCESS_PASSWORD = "password";

    private static String storedString = "initial_string";



    public static void main(String[] args) {

        try (ServerSocket serverSocket = new ServerSocket(PORT)) {

            System.out.println("Server started, waiting for client connection...");



            while (true) {

                Socket clientSocket = serverSocket.accept();

                System.out.println("Client connected from: " + clientSocket.getInetAddress());



                PrintWriter writer = new PrintWriter(clientSocket.getOutputStream(), true);

                BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));



                // Check access password

                String requestPassword = reader.readLine();

                if (!ACCESS_PASSWORD.equals(requestPassword)) {

                    System.out.println("Access password incorrect!");

                    writer.println("Access password incorrect!");

                    clientSocket.close();

                    continue;

                }



                // Send current stored string to client

                writer.println(storedString);



                // Receive and store new string from client

                String newString = reader.readLine();

                if (newString != null && !newString.trim().isEmpty()) {

                    storedString = newString;

                    System.out.println("New string received: " + storedString);

                    writer.println("String stored successfully.");

                } else {

                    writer.println("Empty string received.");

                }



                clientSocket.close();

            }

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

}



//这个服务器会监听8080端口,等待客户端连接。客户端会发送两行信息,第一行是访问密码,
//第二行是字符串。服务器会对密码进行校验,如果密码错误则返回错误信息并断开连接,
//否则将存储的字符串进行处理和存储,然后返回相应的信息。

//请记住,这只是一个简单的示例服务器,没有进行安全校验和错误处理。在实际生产环境中,
//还需要添加适当的安全措施和错误处理机制。

//请确保将`serverUrl`变量根据实际服务器的地址进行修改,以确保与Java服务器的URL地址
//匹配。

阿里云esc只搭建一个接收并保存这个字符串的后端程序。如果发来新的就替换这个字符串

结果:用户打开程序先通过域名访问,该域名会被导向阿里云ecs这个云服务器,该服务器会返回真实的服务器ip地址,此时用户就可以与真实ip的服务器建立联系。此后用户每打开一个新页面,重复上述操作(通过域名先访问

获得ip,然后按照这个ip加载资源),用的url地址都是这个ip对应的字符串

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值