natapp自動獲取免費的動態端口域名


      前段時間,因為客戶有個項目要求跨局域網進行遠程控制桌面,想知道能不能實現。於是查詢了許多資料,了解到需要有公網服務器作為中介才能夠實現,但是公司又沒有公網服務器,於是只有利用花生殼、natapp服務器實現內網穿透服務。但是這些都要收費,免費的域名和端口是隨機變動的,對於測試相當不方便。於是就想設計一款工具能夠自動獲取natapp產生的動態域名與端口。申請natapp的賬號及隧道這里就不用介紹,網上資料一大把,官網也有:https://natapp.cn/article/natapp_newbie可以申請到三個免費不同協議的隧道WEB,TCP,UDP。

    配置好cogfig.ini文件后,Natapp.exe運行起來界面是這樣的,我們需要的是Forwarding后面的值, 剛開始想利用圖像處理的

     

方式進行OCR文字識別,但是Tesseract的識別率太低,訓練可以提高准確率,但是也比較麻煩,於是半途還是放棄了。功夫不負有心人,摸索半天被我尋找到了其他的方法。根據config.ini文件介紹,嘗試使用了Log的功能,想看看log里面都有些啥。原來在Debug日志里面,記錄了得到的所有消息。這樣就有辦法進行自動獲取了。

下面看具體執行步驟吧:

1.首先將官網下載的Natapp.exe文件放置到一目錄下

2.然后打開本工具,選取文件所在地址,如下圖:

 

3.填入natapp提供的authtoken,點擊解析,經過2s左右即可獲取域名端口

WEB協議:

TCP協議:

UDP:協議

       以上,是測試步驟,調用了本人封裝好的DLL,在自己的項目中引用時,只需要提供authtoken,協議類型以及natapp文件的地址即可獲取。后台會自動打開natapp服務,沒有任何窗體展示。

      下面開始重點了,DLL源碼放送:

using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;


namespace NatappToolDll
{
    /// <summary>
    /// 通道協議
    /// </summary>
    public enum TunnelingProtocol
    {
        WEB = 0,
        TCP = 1,
        UDP = 2
    }

    public class NatappResolve
    {
        Process process;
        static string logPath = "log.txt";

        /// <summary>
        /// 開始解析
        /// </summary>
        /// <param name="natappDir">natapp.exe目錄</param>
        /// <param name="authtoken">authtoken碼</param>
        /// <param name="domainNameAndPort">域名和端口號</param>
        /// <returns></returns>
        public bool StartResolve(string natappDir, string authtoken, TunnelingProtocol tunnelingProtocol, out ResolveResult resolveResult)
        {
            resolveResult = new ResolveResult();
            try
            {
                //【1】創建配置文件
                string natappFilePath = natappDir + "\\natapp.exe";
                if (File.Exists(natappFilePath) && authtoken != "")
                {
                    CreatConfigureFile(natappDir, authtoken);
                }
                else
                    return false;
               //【2】打開natapp.exe            
                StartNatapp(natappFilePath);
                Thread.Sleep(1000);

                //【3】分析日志
                using (FileStream fs = new FileStream(logPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                using (StreamReader sr = new StreamReader(fs, System.Text.Encoding.Default))
                {
                    StringBuilder sb = new StringBuilder();              
                    while (!sr.EndOfStream)
                    {
                        sb.AppendLine(sr.ReadLine() + "<br>");
                    }
                    string str = sb.ToString();
                    int x = str.IndexOf("Url");  //定位位置
                    string validData = str.Substring(x, 100);
                    string[] strTmps = validData.Split('"');
                    string[] serverStr = strTmps[2].Split(':');
                    resolveResult.serverUrl = serverStr[0] + ":" + serverStr[1];
                    if (tunnelingProtocol == TunnelingProtocol.TCP || tunnelingProtocol == TunnelingProtocol.UDP)
                        resolveResult.serverPort = int.Parse(serverStr[2]);
                    resolveResult.localIP = strTmps[10].Split(':')[0];
                    resolveResult.localPort = int.Parse(strTmps[10].Split(':')[1]);
                    return true;
                }
            }
            catch (Exception ex)
            {
                return false;
            }
        }


        /// <summary>
        /// 刪除日志文件
        /// </summary>
        /// <param name="directoryPath"> 文件夾路徑 </param>
        /// <param name="fileName"> 文件名稱 </param>
        public static void DeleteFolder()
        {
            DirectoryInfo di = new DirectoryInfo(Application.StartupPath);
            FileInfo[] fis = di.GetFiles();
            foreach (FileInfo fi in fis)
            {
                try
                {
                    if (fi.Name.Contains(logPath))
                    {
                        fi.Delete();
                    }
                }
                catch (Exception ex)
                {
                }
            }
        }

        /// <summary>
        /// 創建natapp的配置文件config.ini
        /// </summary>
        /// <param name="dirPath"></param>
        /// <param name="authtoken"></param>
        /// <param name="clienttoken"></param>
        /// <param name="logFilePath"></param>
        /// <param name="loglevel"></param>
        /// <param name="httpProxy"></param>
        private void CreatConfigureFile(string dirPath, string authtoken, string clienttoken = null)
        {
            string filePath = dirPath + "\\config.ini";
            try
            {
                FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
                StringBuilder sb = new StringBuilder();
                sb.AppendLine("[default]");
                sb.AppendLine("authtoken=" + authtoken);//對應一條隧道的authtoken
                sb.AppendLine("clienttoken=" + clienttoken);//對應客戶端的clienttoken,將會忽略authtoken,若無請留空
                sb.AppendLine("log=" +logPath);//log 日志文件,可指定本地文件, none=不做記錄,stdout=直接屏幕輸出 ,默認為none
                sb.AppendLine("loglevel=DEBUG");//日志等級 DEBUG, INFO, WARNING, ERROR 默認為 DEBUG
                sb.AppendLine("http_proxy=");//代理設置 如 http://10.123.10.10:3128 非代理上網用戶請務必留空

                string str = sb.ToString(); ;
                byte[] data = System.Text.Encoding.Default.GetBytes(str);
                //開始寫入
                fs.Write(data, 0, data.Length);
                //清空緩沖區、關閉流
                fs.Flush();
                fs.Close();
            }
            catch(Exception ex)
            { 
            }

        }

        /// <summary>
        /// 打開natapp.exe 並嵌套到本程序窗體內
        /// </summary>
        private void StartNatapp(string appPath)
        {
            KillProcess("natapp");
            DeleteFolder();
            process = null;
            process = new Process();
            process.StartInfo.FileName = appPath;            // 需要啟動的程序
            process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;    // 為了美觀,啟動的時候最小化程序
            process.Start();
            Thread.Sleep(1000);  // 這里必須等待,否則啟動程序的句柄還沒有創建,不能控制程序
        }

        /// <summary>
        /// 關閉進程
        /// </summary>
        /// <param name="processName">進程名</param>
        private void KillProcess(string processName)
        {
            Process[] myproc = Process.GetProcesses();
            foreach (Process item in myproc)
            {
                if (item.ProcessName == processName)
                {
                    item.Kill();
                }
            }
        }

        /// <summary>
        /// 關閉natapp服務
        /// </summary>
        public void CloseNatappServer()
        {
            KillProcess("natapp");
        }

    }
}

域名端口類:

namespace NatappToolDll
{
    public class ResolveResult
    {
        /// <summary>
        /// 服務器域名 
        /// </summary>
        public string serverUrl { get; set; }
        /// <summary>
        /// 服務器端口
        /// </summary>
        public int? serverPort { get; set; }
        /// <summary>
        /// 本地地址
        /// </summary>
        public string localIP { get; set; }
        /// <summary>
        /// 本地端口
        /// </summary>
        public int localPort { get; set; }
    }
}

調用方法:引用NatappToolDll.dll,執行以下方法即可獲取:

        private void btnStartWeb_Click(object sender, EventArgs e)
        {
            string _natappPath = tbNatappAddress.Text;
            string _authtoken = tbAuthtokenWeb.Text;
            tbProtocol.Text = "WEB";
            StartResolve(_natappPath, NatappToolDll.TunnelingProtocol.WEB,_authtoken);
        }

        /// <summary>
        /// 開始解析
        /// </summary>
        /// <param name="natappPath"></param>
        /// <param name="authtoken"></param>
        public void StartResolve(string natappPath, NatappToolDll.TunnelingProtocol tunnelingProtocol, string authtoken)
        {
            NatappToolDll.ResolveResult rr = new NatappToolDll.ResolveResult();
            bool res = natappResolve.StartResolve(natappPath, authtoken, tunnelingProtocol, out rr);
            tbServerUrl.Text = rr.serverUrl;
            tbServerPort.Text = rr.serverPort.ToString();
            tbLocalIP.Text = rr.localIP;
            tbLocalPort.Text = rr.localPort.ToString();
        }

源碼地址:https://github.com/FreshBreezes/NatappAutoGetUrl.git

使用本工具可方便個人學習,避免每次開啟程序需要手動添加域名和端口的麻煩,如果覺得好用,請多多鼓勵!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM