標籤:
原先一直使用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解析