前段时间,因为客户有个项目要求跨局域网进行远程控制桌面,想知道能不能实现。于是查询了许多资料,了解到需要有公网服务器作为中介才能够实现,但是公司又没有公网服务器,于是只有利用花生壳、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源码放送:

  1. using System;
  2. using System.Diagnostics;
  3. using System.IO;
  4. using System.Text;
  5. using System.Threading;
  6. using System.Windows.Forms;
  7. namespace NatappToolDll
  8. {
  9. /// <summary>
  10. /// 通道协议
  11. /// </summary>
  12. public enum TunnelingProtocol
  13. {
  14. WEB = 0,
  15. TCP = 1,
  16. UDP = 2
  17. }
  18. public class NatappResolve
  19. {
  20. Process process;
  21. static string logPath = "log.txt";
  22. /// <summary>
  23. /// 开始解析
  24. /// </summary>
  25. /// <param name="natappDir">natapp.exe目录</param>
  26. /// <param name="authtoken">authtoken码</param>
  27. /// <param name="domainNameAndPort">域名和端口号</param>
  28. /// <returns></returns>
  29. public bool StartResolve(string natappDir, string authtoken, TunnelingProtocol tunnelingProtocol, out ResolveResult resolveResult)
  30. {
  31. resolveResult = new ResolveResult();
  32. try
  33. {
  34. //【1】创建配置文件
  35. string natappFilePath = natappDir + "\\natapp.exe";
  36. if (File.Exists(natappFilePath) && authtoken != "")
  37. {
  38. CreatConfigureFile(natappDir, authtoken);
  39. }
  40. else
  41. return false;
  42. //【2】打开natapp.exe
  43. StartNatapp(natappFilePath);
  44. Thread.Sleep(1000);
  45. //【3】分析日志
  46. using (FileStream fs = new FileStream(logPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
  47. using (StreamReader sr = new StreamReader(fs, System.Text.Encoding.Default))
  48. {
  49. StringBuilder sb = new StringBuilder();
  50. while (!sr.EndOfStream)
  51. {
  52. sb.AppendLine(sr.ReadLine() + "<br>");
  53. }
  54. string str = sb.ToString();
  55. int x = str.IndexOf("Url"); //定位位置
  56. string validData = str.Substring(x, 100);
  57. string[] strTmps = validData.Split('"');
  58. string[] serverStr = strTmps[2].Split(':');
  59. resolveResult.serverUrl = serverStr[0] + ":" + serverStr[1];
  60. if (tunnelingProtocol == TunnelingProtocol.TCP || tunnelingProtocol == TunnelingProtocol.UDP)
  61. resolveResult.serverPort = int.Parse(serverStr[2]);
  62. resolveResult.localIP = strTmps[10].Split(':')[0];
  63. resolveResult.localPort = int.Parse(strTmps[10].Split(':')[1]);
  64. return true;
  65. }
  66. }
  67. catch (Exception ex)
  68. {
  69. return false;
  70. }
  71. }
  72. /// <summary>
  73. /// 删除日志文件
  74. /// </summary>
  75. /// <param name="directoryPath"> 文件夹路径 </param>
  76. /// <param name="fileName"> 文件名称 </param>
  77. public static void DeleteFolder()
  78. {
  79. DirectoryInfo di = new DirectoryInfo(Application.StartupPath);
  80. FileInfo[] fis = di.GetFiles();
  81. foreach (FileInfo fi in fis)
  82. {
  83. try
  84. {
  85. if (fi.Name.Contains(logPath))
  86. {
  87. fi.Delete();
  88. }
  89. }
  90. catch (Exception ex)
  91. {
  92. }
  93. }
  94. }
  95. /// <summary>
  96. /// 创建natapp的配置文件config.ini
  97. /// </summary>
  98. /// <param name="dirPath"></param>
  99. /// <param name="authtoken"></param>
  100. /// <param name="clienttoken"></param>
  101. /// <param name="logFilePath"></param>
  102. /// <param name="loglevel"></param>
  103. /// <param name="httpProxy"></param>
  104. private void CreatConfigureFile(string dirPath, string authtoken, string clienttoken = null)
  105. {
  106. string filePath = dirPath + "\\config.ini";
  107. try
  108. {
  109. FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
  110. StringBuilder sb = new StringBuilder();
  111. sb.AppendLine("[default]");
  112. sb.AppendLine("authtoken=" + authtoken);//对应一条隧道的authtoken
  113. sb.AppendLine("clienttoken=" + clienttoken);//对应客户端的clienttoken,将会忽略authtoken,若无请留空
  114. sb.AppendLine("log=" +logPath);//log 日志文件,可指定本地文件, none=不做记录,stdout=直接屏幕输出 ,默认为none
  115. sb.AppendLine("loglevel=DEBUG");//日志等级 DEBUG, INFO, WARNING, ERROR 默认为 DEBUG
  116. sb.AppendLine("http_proxy=");//代理设置 如 http://10.123.10.10:3128 非代理上网用户请务必留空
  117. string str = sb.ToString(); ;
  118. byte[] data = System.Text.Encoding.Default.GetBytes(str);
  119. //开始写入
  120. fs.Write(data, 0, data.Length);
  121. //清空缓冲区、关闭流
  122. fs.Flush();
  123. fs.Close();
  124. }
  125. catch(Exception ex)
  126. {
  127. }
  128. }
  129. /// <summary>
  130. /// 打开natapp.exe 并嵌套到本程序窗体内
  131. /// </summary>
  132. private void StartNatapp(string appPath)
  133. {
  134. KillProcess("natapp");
  135. DeleteFolder();
  136. process = null;
  137. process = new Process();
  138. process.StartInfo.FileName = appPath; // 需要启动的程序
  139. process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; // 为了美观,启动的时候最小化程序
  140. process.Start();
  141. Thread.Sleep(1000); // 这里必须等待,否则启动程序的句柄还没有创建,不能控制程序
  142. }
  143. /// <summary>
  144. /// 关闭进程
  145. /// </summary>
  146. /// <param name="processName">进程名</param>
  147. private void KillProcess(string processName)
  148. {
  149. Process[] myproc = Process.GetProcesses();
  150. foreach (Process item in myproc)
  151. {
  152. if (item.ProcessName == processName)
  153. {
  154. item.Kill();
  155. }
  156. }
  157. }
  158. /// <summary>
  159. /// 关闭natapp服务
  160. /// </summary>
  161. public void CloseNatappServer()
  162. {
  163. KillProcess("natapp");
  164. }
  165. }
  166. }

域名端口类:

  1. namespace NatappToolDll
  2. {
  3. public class ResolveResult
  4. {
  5. /// <summary>
  6. /// 服务器域名
  7. /// </summary>
  8. public string serverUrl { get; set; }
  9. /// <summary>
  10. /// 服务器端口
  11. /// </summary>
  12. public int? serverPort { get; set; }
  13. /// <summary>
  14. /// 本地地址
  15. /// </summary>
  16. public string localIP { get; set; }
  17. /// <summary>
  18. /// 本地端口
  19. /// </summary>
  20. public int localPort { get; set; }
  21. }
  22. }

调用方法:引用NatappToolDll.dll,执行以下方法即可获取:

  1. private void btnStartWeb_Click(object sender, EventArgs e)
  2. {
  3. string _natappPath = tbNatappAddress.Text;
  4. string _authtoken = tbAuthtokenWeb.Text;
  5. tbProtocol.Text = "WEB";
  6. StartResolve(_natappPath, NatappToolDll.TunnelingProtocol.WEB,_authtoken);
  7. }
  8. /// <summary>
  9. /// 开始解析
  10. /// </summary>
  11. /// <param name="natappPath"></param>
  12. /// <param name="authtoken"></param>
  13. public void StartResolve(string natappPath, NatappToolDll.TunnelingProtocol tunnelingProtocol, string authtoken)
  14. {
  15. NatappToolDll.ResolveResult rr = new NatappToolDll.ResolveResult();
  16. bool res = natappResolve.StartResolve(natappPath, authtoken, tunnelingProtocol, out rr);
  17. tbServerUrl.Text = rr.serverUrl;
  18. tbServerPort.Text = rr.serverPort.ToString();
  19. tbLocalIP.Text = rr.localIP;
  20. tbLocalPort.Text = rr.localPort.ToString();
  21. }

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

使用本工具可方便个人学习,避免每次开启程序需要手动添加域名和端口的麻烦,如果觉得好用,请多多鼓励!

natapp自动获取免费的动态端口域名的更多相关文章

  1. node获取本机动态IP,并对应修改相关JavaScript文件的IP地址

    目录 由于本机是自动获取分配的动态IP,所以每次重启后需要重新更改与IP相关文件 参考 时间:2018-08-02,更新时间:2018-11-06 注意:在win10环境运行无问题 由于本机是自动获取 ...

  2. 基于jquery的表格动态创建,自动绑定,自动获取值

    最近刚加入GUT项目,学习了很多其他同事写的代码,感觉受益匪浅. 在GUT项目中,经常会碰到这样一个问题:动态生成表格,包括从数据库中读取数据,并绑定在表格中,以及从在页面上通过jQuery新增删除表 ...

  3. 从零到一快速搭建个人博客网站(域名自动跳转www,二级域名使用)(二)

    前言 本篇文章是对上篇文章从零到一快速搭建个人博客网站(域名备案 + https免费证书)(一)的完善,比如域名自动跳转www.二级域名使用等. 域名自动跳转www 这里对上篇域名访问进行优化,首先支 ...

  4. SSH 动态端口forwarding是如何工作的

    好久没有来了,实在是太懒. 经常用SSH的动态端口forwarding 来FQ,使用像这样的命令: ssh -D 9999 -f -C -q -N sshHost.somewhere.com 这个命令 ...

  5. 转载-centos网络配置(手动设置,自动获取)的2种方法

    转载地址:http://blog.51yip.com/linux/1120.html 重新启动网络配置 # service network restart 或 # /etc/init.d/networ ...

  6. Oracle VM Virtual 下CentOS不能自动获取IP地址

    在CentOS配置网卡开机自动获取IP地址: vi /etc/sysconfig/network-scripts/ifcfg-eth0 将 ONBOOT="no" 改为 ONBOO ...

  7. linux如何自动获取ip地址

    第一步:激活网卡 系统装好后默认的网卡是eth0,用下面的命令将这块网卡激活. # ifconfig eth0 up 第二步:设置网卡进入系统时启动 想要每次开机就可以自动获取IP地址上网,就要设置网 ...

  8. centos网络配置方法(手动设置,自动获取)

    不知道为什么最近一段时间网络特别的慢,还老是断,断的时候,局域网都连不上,当我手动设置一下ip后就可以了,搞得我很无语.下面是2种设置网络连接的方法,在说怎么设置前,一定要做好备份工作,特别是对于新手 ...

  9. delphi 自动获取串口

    delphi 自动获取串口   https://blog.csdn.net/Nevermore_anger/article/details/79012875    版权声明:本文为博主原创文章,未经博 ...

随机推荐

  1. 接口使用Http发送post请求工具类

    HttpClientKit import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamR ...

  2. Java实体与Json操作类

    import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.Jav ...

  3. go变量和声明

    go变量和声明 这将是美好的开始和结束,通过写下x = 4,我们查看变量,可以说声明了一个变量并赋值,但是很不幸,go语言变量声明和赋值比这更复杂.通过学习一些简单的示例开始学习变量声明和赋值.然后在 ...

  4. iOS 7 认识 TextKit

    本文由 伯乐在线 - 和谐老约翰 翻译自 Max Seelemann.欢迎加入技术翻译小组.转载请参见文章末尾处的要求. iOS7 的发布给开发者的案头带来了很多新工具.其中一个就是 TextKit( ...

  5. 使用ionic来build安卓apk时,报CordovaError: Requirements check failed for JDK 1.8 or greater

    本地配置了JDK和jre的本地环境变量之后,在命令行中运行Java.javac等都能正常输出,但是在使用ionic cordova build android 来打包ionic的程序时,会提示 Cor ...

  6. 剑指offer——二进制中1的个数(c++)

    题目描述实现一个函数,输入一个整数,输出该数二进制表示中1的个数.例如,把9表示成二进制是1001,则输出为2 常规解法首先把n和1做位运算,判断n的最低位是不是1,然后把1左移一位得到2,再把n和2 ...

  7. divide方法

    java.math.BigDecimal.divide(BigDecimal divisor, RoundingMode roundingMode) 返回一个BigDecimal,其值为(this/除 ...

  8. MySql 主从复制及深入了解

    分享一个不错的mysql文章 https://segmentfault.com/a/1190000008942618

  9. Excel_VBA 常用代码

    单元格编辑后改变背景色(6号,355832828) Dim oldvalue As Variant Private Sub Worksheet_Change(ByVal Target As Range ...

  10. 尝试修改源码需要用到git存一下

    git reflog查看本地记录 git reset --hard 02a3260