使用Java控制路由器获取公网IP

  不知道是公网IP不够用了,还是什么鬼原因,近期我这的联通ADSL拨号很大程度上获取的是一个10.开头的内网IP。虽说通常情况下无需关心,但跑PT,VPN等速度上大打折扣。投诉无果后只能自己写个脚本来自动更换IP。

  其原理很简单,模拟登录到路由器上检查WANIP是否是10.或0.开头,如是则断开重连,以此循环。代码是Java编写,无任何依赖,运行在树莓派上,24小时监视,在运营商完全分配内网IP之前还可以挣扎一阵子。有需要的朋友可以参考下。

  我这用的是TP-LINK WR720N路由器,设置了局域网IP为192.168.30.1 端口88,通过Chrome登录到路由器,可以在开发者工具中查看到Basic加密的Key,替换相应的位置即可。

查询IP的链接

http://192.168.30.1:88/userRpm/StatusRpm.htm

断开拨号的链接

http://192.168.30.1:88/userRpm/StatusRpm.htm?Disconnect=%B6%CF%20%CF%DF&wan=1

重新拨号的链接

http://192.168.30.1:88/userRpm/StatusRpm.htm?Connect=%C1%AC%20%BD%D3&wan=1

代码如下:

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CheckIP {
	private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm:ss");

	public static void main(String[] args) throws Exception {
		do {
			String currentIP = getIP();
			if (currentIP.startsWith("10.") || currentIP.startsWith("0.")) {
				System.out.println(simpleDateFormat.format(new Date())
						+ " 检测到异常:" + currentIP);
				getHtml("http://192.168.30.1:88/userRpm/StatusRpm.htm?Disconnect=%B6%CF%20%CF%DF&wan=1");
				Thread.sleep(1000 * 1);
				getHtml("http://192.168.30.1:88/userRpm/StatusRpm.htm?Connect=%C1%AC%20%BD%D3&wan=1");
				Thread.sleep(1000 * 3);
			}
			Thread.sleep(1000 * 3);
		} while (true);
	}

	private static String getIP() throws Exception {
		String wanPara = getHtml("http://192.168.30.1:88/userRpm/StatusRpm.htm");
		if (null != wanPara) {
			wanPara = wanPara.substring(wanPara.indexOf("var wanPara"),
					wanPara.length());
			wanPara = wanPara.substring(0, wanPara.indexOf(");") + 2);
		}
		return getFirstIp(wanPara);
	}

	private static String getHtml(String address) throws Exception {
		URL url = new URL(address);
		URLConnection connection = url.openConnection();
		connection.setRequestProperty("Authorization", "Basic YWRtaW46d3Npa3Nr");
		connection.connect();
		InputStream inputStream = null;
		StringBuffer stringBuffer = new StringBuffer();
		inputStream = connection.getInputStream();
		BufferedReader bufferedReader = new BufferedReader(
				new InputStreamReader(inputStream));
		String line;
		while ((line = bufferedReader.readLine()) != null) {
			stringBuffer.append(line);
		}
		bufferedReader.close();
		inputStream.close();
		return stringBuffer.toString();
	}

	private static String getFirstIp(String packet) {
		Pattern p = Pattern.compile("\\d+\\.\\d+\\.\\d+\\.\\d+");
		Matcher m = p.matcher(packet);
		if (m.find()) {
			return m.group();
		} else {
			return null;
		}
	}
}

编译

pi@raspberrypi ~ $ javac CheckIP.java

后台运行

pi@raspberrypi ~ $ nohup java CheckIP &

日志

pi@raspberrypi ~ $ tail -f nohup.out