原文地址:http://www.yxxrui.cn/article/179.shtml

未经许可请勿转载,如有疑问,请联系作者:yxxrui@163.com

我遇到的问题:公司的网络没有固定的公网IP地址,但是需要能够保证的是,每次动态分配的IP地址均为独立的公网IP,只是每次分配后会在1-2天后更换,或者重启路由器后更换,为了能够把这个公网IP利用起来,大家常用的是使用花生壳之类的软件来操作,我使用过花生壳的多款产品,挺好的,就是有一下几个缺点:

1、需要使用花生壳上购买的域名才行,或者使用免费的壳域名,其丑无比

2、不稳定,也很慢

3、限制流量,超流量需要收费

4、限制端口,特定端口需要收费

5、需要在电脑上运行一个花生壳的软件

解决方案:但是为了解决问题,我开始摸索自己搞定它,公司域名从阿里云上购买,阿里云提供云解析技术免费版,提供通过api来管理域名的功能,当我看到该文档的时候直接就看到了希望,解决起来绝对没问题了。首先需要确认一下,有两种情况:

1、公司服务器直接接入网线,这个时候服务器的IP就是公网IP

2、公司服务器链接公司路由器,路由器链接网线,这个时候路由器上是公网IP,而服务器上是局域网IP

第一种情况最简单了,不需要设置什么了,第二种情况需要到路由器设置界面设置端口转发或者直接将全部端口映射到内网的服务器IP上,这样的话,访问公网IP的某个端口时相当于访问内网IP的映射端口,比如路由器IP为125.120.83.30,内网IP为192.168.168.168。可以将路由器中80端口映射到192.168.168.168的80端口上。

到阿里云控制台申请accessKeyIdaccessKeySecret,用来调用API的,为了简单起见,先给域名添加一条解析记录,这样就不需要在程序里判断该域名是否已创建,然后可以直接修改解析记录了。比如我的域名为yxxrui.cn,记录值为blog,也就是要把子域名blog.yxxrui.cn指向我自己电脑125.120.83.30上。

下边直接贴出代码:

using System;
using System.Configuration;
using System.Net;
using System.Text;
using Aliyun.Acs.Alidns.Model.V20150109;
using Aliyun.Acs.Core;
using Aliyun.Acs.Core.Profile; namespace AliyunDomain
{
class Program
{
private static readonly string RegionId=GetConfig("regionId");
private static readonly string AccessKeyId=GetConfig("accessKeyId");
private static readonly string AccessKeySecret=GetConfig("accessKeySecret");
private static string _recordId = GetConfig("recordId");
private static readonly string Domain = GetConfig("domain");
private static readonly string Rr = GetConfig("rr");
private static readonly IClientProfile ClientProfile =
DefaultProfile.GetProfile(RegionId, AccessKeyId,AccessKeySecret);
private static readonly IAcsClient Client = new DefaultAcsClient(ClientProfile); static void Main(string[] args)
{
if (string.IsNullOrWhiteSpace(_recordId))
{
//如果没有获取过,那么获取一下,然后保存起来
_recordId = GetRecordId(Domain, Rr);
SaveConfig("recordId",_recordId);
}
if (_recordId == "") return;
//获取成功,并且有变化时
string lastIp = GetConfig("lastIP");
string curIp = GetIp();
if (!curIp.Equals("") && !lastIp.Equals(curIp))
{
var request = new UpdateDomainRecordRequest
{
RecordId = _recordId,
RR = Rr,
Type = "A",
Value = curIp,
TTL = 600,
Priority = 10
};
Client.DoAction(request);
SaveConfig("lastIP", curIp);
}
} #region 保存配置信息
/// <summary>
/// 保存配置信息
/// </summary>
/// <param name="name"></param>
/// <param name="value"></param>
private static void SaveConfig(string name,string value)
{
var cfa = ReadAppConfig();
cfa.AppSettings.Settings[name].Value = value;
cfa.Save();
}
#endregion #region 获取配置项
/// <summary>
/// 获取配置项
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
private static string GetConfig(string name)
{
var cfa = ReadAppConfig();
return cfa.AppSettings.Settings[name].Value;
}
#endregion #region 调用阿里云接口获取域名的唯一记录ID
/// <summary>
/// 调用阿里云接口获取域名的唯一记录ID
/// </summary>
/// <param name="domain">域名</param>
/// <param name="rr">子域名</param>
/// <returns></returns>
private static string GetRecordId(string domain,string rr)
{
DescribeDomainRecordsRequest reqq = new DescribeDomainRecordsRequest
{
DomainName = domain,
RRKeyWord = rr
};
var rss = Client.GetAcsResponse(reqq);
foreach (var record in rss.DomainRecords)
{
if (record.DomainName.Equals(domain) && record.RR.Equals(rr))
{
return record.RecordId;
}
}
return "";
}
#endregion #region 获取公网IP
/// <summary>
/// 获取当前电脑的真实外网IP地址,可以自行修改成稳定的
/// </summary>
/// <returns></returns>
private static string GetIp()
{
string ip = "";
try
{
//获取或设置用于向Internet资源的请求进行身份验证的网络凭据
WebClient myWebClient = new WebClient {
Credentials = CredentialCache.DefaultCredentials };
//从指定网站下载数据
Byte[] pageData = myWebClient.DownloadData(
"http://www.yxxrui.cn/yxxrui_cabangs_api/myip.ashx");
//如果获取网站页面采用的是GB2312,则使用这句
string pageHtml = Encoding.Default.GetString(pageData);
//如果获取网站页面采用的是UTF-8,则使用这句
//string pageHtml = Encoding.UTF8.GetString(pageData);
return pageHtml;
}
catch (WebException webEx)
{
}
return ip;
}
#endregion #region 获取配置文件
private static Configuration _config;
private static Configuration ReadAppConfig()
{
if (_config == null)
{
string configPath = @"app.config";
_config = ConfigurationManager.OpenMappedExeConfiguration(
new ExeConfigurationFileMap()
{
ExeConfigFilename = configPath
}, ConfigurationUserLevel.None);
}
//MessageBox.Show(config.AppSettings.Settings["serverIp"].Value);
return _config;
}
#endregion
}
}

app.config文件内容如下:

本代码为C#代码,建议将项目设置为winform程序,不要设置为控制台程序,否则每次执行时会弹出黑色的控制台,很恶心人的。该代码未实现自动检测和执行(如需程序创建计划任务,可联系我),只是做了以下工作:

1、获取当前电脑真实公网IP

2、查看当前IP是否有变化

3、若无变化直接退出,若有变化则修改域名解析设置

这些并不能达到实时解析。但可以通过使用window 操作系统中的任务计划程序,制定计划,每(1)分钟执行该软件一次即可。

代码与源码压缩包下载地址:http://www.yxxrui.cn/article/179.shtml

最新文章

  1. UE移植到SAE云平台
  2. java 选择排序
  3. EasyARM i.mx28学习笔记——开箱试用总结
  4. asp.net 获取系统的根目录
  5. Thread.join()分析方法
  6. Thinkphp5.0 在自己定义一个公共方法的控制器并且继承了Controller类的时候报错
  7. NPM实用指北
  8. myeclipse附加源码进行查看的方法
  9. Shodan的http.favicon.hash语法详解与使用技巧
  10. kettle学习笔记及实践
  11. java 容器 集合 用法
  12. 第三篇-ubuntu18.04下截图快捷键
  13. C#标准体重判断
  14. 12.python-metaclass元类
  15. Luogu4512 【模板】多项式除法(多项式求逆+NTT)
  16. php stomp.dll 下载地址
  17. mysql 意向锁的作用
  18. 切换nPar或vPar的启动模式
  19. 高中生的IT之路-1.5西餐厅服务生
  20. scrapy - grab english name

热门文章

  1. java学生简单管理系统
  2. CentOS6.5配置KVM
  3. harbor私有仓库部署
  4. 【GDKOI2014】JZOJ2020年8月13日提高组T1 阶乘
  5. Jdk源码-集合类主要原理和解析
  6. moviepy音视频剪辑:视频剪辑基类VideoClip的__init__构造方法参数has_constant_size的作用
  7. PyQt(Python+Qt)学习随笔:QListView的isWrapping属性
  8. Android的intent
  9. ATT&amp;CK 实战 - 红日安全 vulnstack (一) 靶机渗透
  10. Day1-7【Scrum 冲刺博客集合】