码迷,mamicode.com
首页 > 其他好文 > 详细

更新TP-LINK路由器的外网IP到花生壳动态IP解析

时间:2015-06-15 10:47:19      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:

原先一直使用TP-LINK路由器本身自带的花生壳动态DNS加路由器的端口映射功能,可以从外网直接访问到到内网电脑端口。

后来发现花生壳提供的解析IP不能访问内网电脑了,经过一番检查,发现路由器中的外网IP与访问外网网页时所显示器的IP地址不一致,

使用访问网页时的IP测试不能访问到内网,使用路由器上显示器的外网IP倒是可以访问到内网,

应该是ISP提供商(本人用的是联通宽带)使用了NAT转换导致的。

又是一番调查,花生壳和其它的动态DNS服务提供商倒是提供了可能的解决方案,就是根据线路不同内部进行不同处理,

本人估计是可能可以解决NAT转换导致的IP地址问题,但是,最重要一点,这种服务是收费服务,只能另想办法了。

后来又发现花生壳提供手动更新动态IP功能,也就是使用HTTP的GET方法来编程手动更新IP地址,

又调查发现应该可以从路由器的管理网页中得到外网IP,所以经过调查测试,确实可以实现,再加上软件中进行定时自动更新,可以实现类似花生壳客户端的自动更新IP功能。

将使用的主要代码【C#】记录如下:

        /// <summary>
        /// 取得TP-LINK路由器的外网IP地址
        /// 本函数假设路由器已处于连网状态,不再对是否连网状态进行判断
        /// </summary>
        /// <param name="strTPIP">TP-LINK路由器的IP地址</param>
        /// <param name="strUserName">TP-LINK路由器的管理用户名</param>
        /// <param name="strPassword">TP-LINK路由器的管理用户密码</param>
        /// <returns>外网IP地址,为空表示获取失败</returns>
        private string GetWanIP(string strTPIP, string strUserName, string strPassword)
        {
            // 包含TP-LINK路由器状态信息的网页URL
            string strTPURL = "http://" + strTPIP + "/userRpm/StatusRpm.htm";

            // 设置获取状态信息网页内容的相关参数
            System.Net.HttpWebRequest objRequest = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(strTPURL);
            objRequest.Referer = strTPURL;
            objRequest.Credentials = new System.Net.NetworkCredential(strUserName, strPassword);
            
            // 取得结果信息内容
            SetLogMessage(0, "尝试获取路由器状态信息内容");
            System.Net.HttpWebResponse objResponse = (System.Net.HttpWebResponse)objRequest.GetResponse();

            SetLogMessage(1, "已取得路由器状态信息");
            // 取得结果内容文本
            System.IO.StreamReader objResponseReader = new System.IO.StreamReader(objResponse.GetResponseStream(), Encoding.Default);
            string strResponseText = objResponseReader.ReadToEnd();
            objResponseReader.Close();
            objResponse.Close();

            // 查找包含外网IP地址的数据数组位置
            SetLogMessage(1, "查找包含外网IP地址的数据数组位置");
            int intPos = strResponseText.IndexOf("var wanPara = new Array");
            if (intPos < 0)
            {
                SetLogMessage(0, "*** 查找包含外网IP地址的数据数组位置失败");
                return "";
            }

            // 查找外网IP地址位置
            SetLogMessage(1, "查找外网IP地址位置");
            int intPos2 = strResponseText.IndexOf("\",\n\"", intPos);
            if (intPos2 < 0)
            {
                SetLogMessage(0, "*** 查找外网IP地址位置失败");
                return "";
            }

            // 查找外网IP地址结束位置
            SetLogMessage(1, "查找外网IP地址结束位置");
            int intPos3 = strResponseText.IndexOf("\"", intPos2 + 4);
            if (intPos3 < 0)
            {
                SetLogMessage(0, "*** 查找外网IP地址结束位置失败");
                return "";
            }

            // 得到外网IP地址
            int intIPPos = intPos2 + 4;
            string strWanIP = strResponseText.Substring(intIPPos, intPos3 - intIPPos);
            SetLogMessage(0, "得到结果外网IP地址:[" + strWanIP + "]");

            return strWanIP;
        }

        /// <summary>
        /// 更新动态IP地址到花生壳
        /// </summary>
        /// <param name="strOrayUserName">花生壳用户名</param>
        /// <param name="strOrayPassword">花生壳密码</param>
        /// <param name="strHostName">花生壳域名(多个域名时用逗号隔开)</param>
        /// <param name="strWanIP">要更新的IP,也可为空,为空时由花生壳得到的IP地址为准</param>
        /// <returns>是否成功</returns>
        private bool UpdateOrayDdnsIP(string strOrayUserName, string strOrayPassword, string strHostName, string strWanIP)
        {
            // 更新DDNS的URL
            string strUpdateURL = "http://ddns.oray.com/ph/update?hostname=" + strHostName + "&myip=" + strWanIP;

            // 创建HTTP请求对象
            System.Net.HttpWebRequest objRequest = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(strUpdateURL);

            // 设置相关参数
            objRequest.UserAgent = "Oray";
            objRequest.Method = "GET";
            
            //获得用户名密码的Base64编码
            string strBase64Code = Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", strOrayUserName, strOrayPassword)));

            //添加Authorization到HTTP头
            objRequest.Headers.Add("Authorization", "Basic " + strBase64Code);


            // 尝试更新并取得结果信息
            SetLogMessage(0, "尝试更新动态IP到花生壳");
            System.Net.HttpWebResponse objResponse = (System.Net.HttpWebResponse)objRequest.GetResponse();

            // 得到结果信息文本
            SetLogMessage(1, "更新动态IP到花生壳完成");
            System.IO.StreamReader objResponseReader = new System.IO.StreamReader(objResponse.GetResponseStream(), Encoding.Default);
            string strResponseText = objResponseReader.ReadToEnd();
            objResponseReader.Close();
            objResponse.Close();

            SetLogMessage(0, "更新结果信息:[" + strResponseText + "]");

            // 检查结果是否成功
            if (strResponseText.IndexOf("good") >= 0 || strResponseText.IndexOf("nochg") >= 0)
            {
                SetLogMessage(1, "更新动态IP地址成功");
                return true;
            }
            else
            {
                SetLogMessage(0, "*** 更新动态IP地址失败");
                return false;
            }

        }

 以上代码只适用于TP-LINK路由器,在TP-LINK路由器TL-WR845N型号上测试通过,因为没有测试其它型号,所以不能保证其它型号的路由器可以正常使用。

如果TP-LINK其它型号路由器不能使用,可以查看状态显示器网页URL是否与上面代码中URL一致,并且使用HTTP抓包工具查看网页Header内容及Response内容,

对URL、进行GET时的Header内容以及Response的内容中的外网IP所在位置查找字符串方法进行调整,应该是可以实现的。

同理,对于其它厂商的路由器,本人感觉也是可以同样道理来实现,查看路由器状态信息页面源代码以及使用HTTP抓包工具查看相关信息,应该可以实现类似功能。

 

更新TP-LINK路由器的外网IP到花生壳动态IP解析

标签:

原文地址:http://www.cnblogs.com/lanma/p/4576498.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!