近日為了滿足2個屋子裡人的通訊需要,需要將本地的外網IP告訴給另一個屋子裡的人。以前都是在群裡喊一句,我這裡的IP是XXXX,有一天自己突發奇想,想通過程式來實現這個自動化通知的過程。於是自己給自己定了需求。
需求:基本目標實現開機將本地的路由WAN口IP通知對方。
思考:如果才能實現自動通知呢。
首先,要有一個公用的空間,可以作為通知的載體。
其次,需要傳輸機制把通知發出去。
經過思考,我想到了電子郵件,郵箱是每個人都有的,email是可以用程度發的。於是需求變成了通過發郵件的方式把最新擷取到的IP發出來。解決的思路有 了,最大的問題是如何擷取外網IP,開始嘗試擷取本地IP,這個顯然是沒用的,因為機器是在內網環境,擷取到的只是內網IP,後來試圖想通過擷取外網 IP,比如訪問一個XXX網站的形式來擷取IP,這種網站還真不少,但是擷取到的都是公網IP,學過網路的人都知道公網IP很少,往往只是在網路節點上的 IP,這種IP對我一個ADSL使用者來說幾乎就沒任何意義。其實我需要的只是路由的WAN口IP。網上搜了一下,也沒找到合適的。在幾乎絕望的時候,我想 到了代理,我能不能通過訪問路由器的方式來擷取IP呢,我試圖用telnet登陸路由,試圖用路由命令來操作路由,結果和我想象的一樣,家用路由畢竟不是 伺服器層級的路由,根本沒有對外提供的訪問命令,只能通過web的方式來實現對路由的設定。自己再次陷入了絕望,後來我開啟fireBug,試圖找到IP 那個查看IP跳轉的頁面。結果被我找到了,http://192.168.1.1/userRpm/StatusRpm.htm,點開頁面查看響應,傳過 來的就是網頁的部分資訊。OK,這就是我想要的IP。我突然興奮起來,但是這似乎還不夠,因為每次登陸路由時要輸入使用者名稱和密碼。網上搜搜,這個其實不 難,代理服務程式就那樣寫的。經過一晚上的思考和實踐WAN口IP算是被我搞出來了。 Java代碼 package com.eehome.app.mail.utils; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.Authenticator; import java.net.URL; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.eehome.app.mail.IMailConstant; import com.eehome.app.mail.model.RouterPassAuth; /** * @author wensong * 2010-9-4 下午03:34:58 */ public class RouteIpUtils { private final static RouteIpUtils routeIpUtils = new RouteIpUtils(); private RouteIpUtils() { } public static RouteIpUtils getInstance() { //驗證器工具的執行個體進行註冊 Authenticator.setDefault(new RouterPassAuth()); return routeIpUtils; } public String getRouteIp() throws IOException { StringBuffer wanPacket = getWanPacket(); return getFirstIp(wanPacket); } /** * 獲得路由Web中的狀態頁面上的資料 * * @return * @throws IOException */ private StringBuffer getWanPacket() throws IOException { URL url = new URL(IMailConstant.ROUTE_WEB_STATE); InputStream ins = null; try { ins = url.openConnection().getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(ins)); String str; boolean flag = false; StringBuffer wanPacket = new StringBuffer(); int num = 3; while ((str = reader.readLine()) != null && num > 0) { if (str.contains("var wanPara = new Array(")) { flag = true; } if (flag) { wanPacket.append(str); num--; } } return wanPacket; }finally{ if(ins!=null){ ins.close(); } } } private String getFirstIp(StringBuffer wanPacket) { // 找出資料包中第一個匹配的IP,即為Ip Pattern p = Pattern.compile("\\d+\\.\\d+\\.\\d+\\.\\d+"); Matcher m = p.matcher(wanPacket);&nb