java获取本地局域网的外网IP ....

来源:互联网 发布:淘宝卖家好评的好处 编辑:程序博客网 时间:2024/06/02 12:08

近日为了满足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代码  收藏代码
  1. package com.eehome.app.mail.utils;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.InputStreamReader;  
  7. import java.net.Authenticator;  
  8. import java.net.URL;  
  9. import java.util.regex.Matcher;  
  10. import java.util.regex.Pattern;  
  11.   
  12. import com.eehome.app.mail.IMailConstant;  
  13. import com.eehome.app.mail.model.RouterPassAuth;  
  14.   
  15. /** 
  16.  * @author wensong 
  17.  * 2010-9-4 下午03:34:58 
  18.  */  
  19. public class RouteIpUtils {  
  20.   
  21.     private final static RouteIpUtils routeIpUtils = new RouteIpUtils();  
  22.       
  23.       
  24.     private RouteIpUtils() {  
  25.   
  26.     }  
  27.   
  28.     public static RouteIpUtils getInstance() {  
  29.         //验证器工具的实例进行注册  
  30.         Authenticator.setDefault(new RouterPassAuth());  
  31.         return routeIpUtils;  
  32.     }  
  33.   
  34.     public String getRouteIp() throws IOException {  
  35.         StringBuffer wanPacket = getWanPacket();  
  36.         return getFirstIp(wanPacket);  
  37.     }  
  38.   
  39.     /** 
  40.      * 获得路由Web中的状态页面上的数据 
  41.      *  
  42.      * @return 
  43.      * @throws IOException 
  44.      */  
  45.     private StringBuffer getWanPacket() throws IOException {  
  46.         URL url = new URL(IMailConstant.ROUTE_WEB_STATE);  
  47.         InputStream ins = null;  
  48.         try {  
  49.             ins = url.openConnection().getInputStream();  
  50.             BufferedReader reader = new BufferedReader(new InputStreamReader(ins));  
  51.             String str;  
  52.             boolean flag = false;  
  53.             StringBuffer wanPacket = new StringBuffer();  
  54.             int num = 3;  
  55.             while ((str = reader.readLine()) != null && num > 0) {  
  56.                 if (str.contains("var wanPara = new Array(")) {  
  57.                     flag = true;  
  58.                 }  
  59.                 if (flag) {  
  60.                     wanPacket.append(str);  
  61.                     num--;  
  62.                 }  
  63.             }  
  64.             return wanPacket;  
  65.         }finally{  
  66.             if(ins!=null){  
  67.                 ins.close();  
  68.             }  
  69.         }  
  70.     }  
  71.   
  72.     private String getFirstIp(StringBuffer wanPacket) {  
  73.         // 找出数据包中第一个匹配的IP,即为Ip  
  74.         Pattern p = Pattern.compile("\\d+\\.\\d+\\.\\d+\\.\\d+");  
  75.         Matcher m = p.matcher(wanPacket);  
  76.         if (m.find()) {  
  77.             return m.group();  
  78.         } else {  
  79.             return null;  
  80.         }  
  81.     }  
  82.       
  83.     public static void main(String[] args) {  
  84.         try {  
  85.             System.out.println(RouteIpUtils.getInstance().getRouteIp());  
  86.         } catch (IOException e) {  
  87.             // TODO Auto-generated catch block  
  88.             e.printStackTrace();  
  89.         }  
  90.     }  
  91. }  
Java代码  收藏代码
  1. package com.eehome.app.mail;  
  2.   
  3. public interface IMailConstant {  
  4.   
  5.     /** 
  6.      * 发件人地址 
  7.      */  
  8.     public final static String NOTIFY_EMAIL_MESSAGE_FROM = "wensong1987@126.com";  
  9.   
  10.     /** 
  11.      * 提醒邮件标题前缀 
  12.      */  
  13.     public final static String NOTIFY_EMAIL_MESSAGE_PRE_TITLE = "通知:服务器IP提醒————";  
  14.   
  15.     /** 
  16.      * 路由用户名 
  17.      */  
  18.     public final static String ROUTE_USER = "admin";  
  19.   
  20.     /** 
  21.      * 路由密码 
  22.      */  
  23.     public final static String ROUTE_PWD = "huang";  
  24.   
  25.     /** 
  26.      * 路由Web记录状态的页面,里面包含了Wan口ip 
  27.      */  
  28.     public final static String ROUTE_WEB_STATE = "http://192.168.1.1:83/userRpm/StatusRpm.htm?Connect=连 接&wan=1";  
  29.   
  30.     /** 
  31.      * 轮询时间 10分钟 
  32.      */  
  33.     public final static long POLLING_TIME = 10 * 60 * 1000;  
  34.   
  35.     /** 
  36.      * email文件地址 
  37.      */  
  38.     public final static String EMAIL_FILE_PATH = "/root/mail/mail.txt";  
  39.   
  40.     /** 
  41.      * log4j存放地址 
  42.      */  
  43.     public final static String LOG4J_FILE_PATH = "/root/mail/log/log4j.properties";  
  44.   
  45.     /** 
  46.      * 匹配email的正则 
  47.      */  
  48.     public final static String EMAIL_REG = "[A-Za-z0-9](?:[0-9a-zA-Z_]?\\.?){4,24}@[0-9a-zA-Z_-]{1,59}\\.(?:[0-9a-zA-Z]\\.?[0-9a-zA-Z]?){2,3}";  
  49. }  
Java代码  收藏代码
  1. package com.eehome.app.mail.model;  
  2.   
  3. import java.net.Authenticator;  
  4. import java.net.PasswordAuthentication;  
  5.   
  6. import com.eehome.app.mail.IMailConstant;  
  7.   
  8.   
  9. public class RouterPassAuth extends Authenticator {  
  10.       
  11.     @Override  
  12.     public PasswordAuthentication getPasswordAuthentication() {  
  13.         return new PasswordAuthentication(IMailConstant.ROUTE_USER,  
  14.                 IMailConstant.ROUTE_PWD.toCharArray());  
  15.     }  
  16.   
  17. }  

      考虑到路由IP是动态IP,过一段时间就会变化,我给程序设计了一个轮询机制来检测IP,变化,用一个调度任务来定时获取IP,进行比较,再决定是否发送邮件。

Java代码  收藏代码
  1. package com.eehome.app.mail.task;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.Arrays;  
  5.   
  6. import org.apache.commons.logging.Log;  
  7. import org.apache.commons.logging.LogFactory;  
  8. import org.apache.log4j.PropertyConfigurator;  
  9. import org.springframework.beans.factory.BeanFactory;  
  10. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  11. import org.springframework.mail.javamail.JavaMailSender;  
  12.   
  13. import com.eehome.app.mail.IMailConstant;  
  14. import com.eehome.app.mail.model.IpNotifyMessage;  
  15. import com.eehome.app.mail.utils.RouteIpUtils;  
  16.   
  17. /** 
  18.  * 邮件提醒任务 
  19.  * @author wensong 
  20.  * 2010-9-5 下午11:12:17 
  21.  */  
  22. public class NotifyEmailSendTask implements Runnable {  
  23.   
  24.     private String[] toMails;  
  25.     private Log logger = LogFactory.getLog(this.getClass());  
  26.   
  27.     private static String ip = "192.168.1.110";  
  28.   
  29.     static {  
  30.         PropertyConfigurator.configure(IMailConstant.LOG4J_FILE_PATH);  
  31.     }  
  32.   
  33.     private static BeanFactory factory = new ClassPathXmlApplicationContext(  
  34.             "application-context.xml");  
  35.   
  36.     public NotifyEmailSendTask(String[] toMails) {  
  37.         this.toMails = toMails;  
  38.     }  
  39.   
  40.     public void run() {  
  41.         String routerIp = null;  
  42.         try {  
  43.             routerIp = RouteIpUtils.getInstance().getRouteIp();  
  44.         } catch (IOException e1) {  
  45.             logger.warn("连接路由中断,或者路由连接异常:" + e1);  
  46.         }  
  47.         try {  
  48.             if (routerIp != null&&!routerIp.equals("0.0.0.0")) {  
  49.                 if (!routerIp.equals(ip)) {  
  50.                     if (!ip.equals("192.168.1.110"))  
  51.                         logger.info("路由IP发生变化,执行发送邮件任务");  
  52.                     StringBuffer context = new StringBuffer().append(  
  53.                             "今日Host:\n").append("eehome.com  ")  
  54.                             .append(routerIp);  
  55.                     if (!ip.equals("192.168.1.110")) {  
  56.                         context = new StringBuffer().append("Host变化如下:\n")  
  57.                                 .append("eehome.com  ").append(routerIp);  
  58.                     }  
  59.   
  60.                     // 构造邮件消息对象  
  61.                     IpNotifyMessage message = new IpNotifyMessage(toMails,  
  62.                             context.toString());  
  63.                     // 发邮件  
  64.                     JavaMailSender mailSender = (JavaMailSender) factory  
  65.                             .getBean("javaMailSender");  
  66.                     logger.info("发送邮件,发送邮箱为:" + Arrays.toString(toMails));  
  67.   
  68.                     mailSender.send(message);  
  69.                     ip = routerIp;  
  70.                 } else {  
  71.                     logger.debug("上次记录的IP为:" + ip + ", 最新路由IP为:" + routerIp  
  72.                             + " 轮询结果将不发送邮件");  
  73.                 }  
  74.             }  
  75.         } catch (Exception e) {  
  76.             logger.warn("发送邮件异常:" + e);  
  77.         }  
  78.   
  79.     }  
  80.   
  81. }  
 
Java代码  收藏代码
  1. package com.eehome.app.mail.task;  
  2.   
  3. import java.util.concurrent.TimeUnit;  
  4.   
  5. import com.eehome.app.mail.IMailConstant;  
  6. import com.eehome.app.mail.utils.EmailsProvider;  
  7. import com.eehome.core.task.EeHomeScheduledExecutor;  
  8.   
  9. /** 
  10.  * 邮件任务调度,采用轮询的方式来检查路由IP是否发生改变,如果改变发送邮件 
  11.  *  
  12.  * @author wensong 2010-9-4 下午03:34:58 
  13.  */  
  14. public class IpNotifyEmailSchedule {  
  15.   
  16.     public static void main(String[] args) {  
  17.         String[] mails = EmailsProvider.getInstance().getEmailArrays();  
  18.         EeHomeScheduledExecutor.getScheduledExecutor().scheduleWithFixedDelay(  
  19.                 new NotifyEmailSendTask(mails), 0, IMailConstant.POLLING_TIME,  
  20.                 TimeUnit.MILLISECONDS);  
  21.     }  
  22. }  

 

Java代码  收藏代码
  1. package com.eehome.app.mail.model;  
  2.   
  3. import java.util.Date;  
  4.   
  5. import org.springframework.mail.SimpleMailMessage;  
  6.   
  7. import com.eehome.app.mail.IMailConstant;  
  8. import com.eehome.app.mail.utils.DateUtils;  
  9.   
  10. public class IpNotifyMessage extends SimpleMailMessage {  
  11.   
  12.     private static final long serialVersionUID = -3236307360187426650L;  
  13.   
  14.     public IpNotifyMessage(String toMail, String toText) {  
  15.         // 设置邮件标题:提醒邮件标题前缀+当前时间  
  16.         setSubject(IMailConstant.NOTIFY_EMAIL_MESSAGE_PRE_TITLE  
  17.                 + DateUtils.getTimeNow());  
  18.         setFrom(IMailConstant.NOTIFY_EMAIL_MESSAGE_FROM);  
  19.         setSentDate(new Date());  
  20.         setTo(toMail);  
  21.         setText(toText);  
  22.     }  
  23.       
  24.     public IpNotifyMessage(String[] toMails,String toText){  
  25.         // 设置邮件标题:提醒邮件标题前缀+当前时间  
  26.         setSubject(IMailConstant.NOTIFY_EMAIL_MESSAGE_PRE_TITLE  
  27.                 + DateUtils.getTimeNow());  
  28.         setFrom(IMailConstant.NOTIFY_EMAIL_MESSAGE_FROM);  
  29.         setSentDate(new Date());  
  30.         setTo(toMails);  
  31.         setText(toText);  
  32.     }  
  33. }  

 

Java代码  收藏代码
  1. package com.eehome.app.mail.exception;  
  2.   
  3. public class FileIsNotExistException extends Exception {  
  4.   
  5.     /** 
  6.      * 文件不存在异常 
  7.      */  
  8.     private static final long serialVersionUID = -2545287258814097123L;  
  9.   
  10.     public FileIsNotExistException() {  
  11.         super();  
  12.     }  
  13.   
  14.     public FileIsNotExistException(String message, Throwable cause) {  
  15.         super(message, cause);  
  16.     }  
  17.   
  18.     public FileIsNotExistException(String message) {  
  19.         super(message);  
  20.     }  
  21.   
  22.     public FileIsNotExistException(Throwable cause) {  
  23.         super(cause);  
  24.     }  
  25.   
  26. }  
 
Java代码  收藏代码
  1. package com.eehome.app.mail.utils;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.File;  
  5. import java.io.FileInputStream;  
  6. import java.io.FileNotFoundException;  
  7. import java.io.IOException;  
  8. import java.io.InputStream;  
  9. import java.io.InputStreamReader;  
  10. import java.util.ArrayList;  
  11. import java.util.List;  
  12. import java.util.regex.Matcher;  
  13. import java.util.regex.Pattern;  
  14.   
  15. import org.apache.commons.logging.Log;  
  16. import org.apache.commons.logging.LogFactory;  
  17. import org.apache.log4j.PropertyConfigurator;  
  18.   
  19. import com.eehome.app.mail.IMailConstant;  
  20.   
  21. public class EmailsProvider {  
  22.   
  23.     private final static EmailsProvider provider = new EmailsProvider();  
  24.     private Log logger = LogFactory.getLog(this.getClass());  
  25.   
  26.     static {  
  27.         PropertyConfigurator.configure(IMailConstant.LOG4J_FILE_PATH);  
  28.     }  
  29.   
  30.     private EmailsProvider() {  
  31.   
  32.     }  
  33.   
  34.     public static EmailsProvider getInstance() {  
  35.         return provider;  
  36.     }  
  37.   
  38.     /** 
  39.      * 获得Email数组 
  40.      *  
  41.      * @return 
  42.      */  
  43.     public String[] getEmailArrays() {  
  44.         StringBuilder sb = getEmailStrBuilder();  
  45.         if (sb != null) {  
  46.             List<String> mailArrays = getEmails(sb);  
  47.             return (String[]) mailArrays.toArray(new String[mailArrays.size()]);  
  48.         } else {  
  49.             return null;  
  50.         }  
  51.     }  
  52.   
  53.     /** 
  54.      * 从指定email配置中获取email 
  55.      *  
  56.      * @return 
  57.      */  
  58.     private StringBuilder getEmailStrBuilder() {  
  59.         File file = new File(IMailConstant.EMAIL_FILE_PATH);  
  60.         InputStream ins = null;  
  61.         StringBuilder stringBuilder = new StringBuilder();  
  62.         try {  
  63.             ins = new FileInputStream(file);  
  64.             BufferedReader reader = new BufferedReader(new InputStreamReader(  
  65.                     ins));  
  66.             String str;  
  67.             while ((str = reader.readLine()) != null) {  
  68.                 stringBuilder.append(str).append(",");  
  69.             }  
  70.             return stringBuilder;  
  71.         } catch (FileNotFoundException e) {  
  72.             logger.info(file.getPath() + "文件不存在");  
  73.             return null;  
  74.         } catch (IOException e) {  
  75.             logger.info("文件操作异常:" + e);  
  76.             return null;  
  77.         } finally {  
  78.             try {  
  79.                 ins.close();  
  80.             } catch (IOException e) {  
  81.                 logger.info("文件关闭异常:" + e);  
  82.                 return null;  
  83.             }  
  84.         }  
  85.   
  86.     }  
  87.   
  88.     /** 
  89.      * 通过正则匹配字符 
  90.      * @param stringBuilder 
  91.      * @return 
  92.      */  
  93.     private List<String> getEmails(StringBuilder stringBuilder) {  
  94.         List<String> mails = new ArrayList<String>();  
  95.   
  96.         // 创建正则表达式  
  97.         Pattern p = Pattern.compile(IMailConstant.EMAIL_REG);  
  98.         Matcher m = p.matcher(stringBuilder);  
  99.   
  100.         if (logger.isDebugEnabled()) {  
  101.             logger.debug("文件读取的字符串stringBuilder:" + stringBuilder);  
  102.         }  
  103.   
  104.         // 找到匹配的字符串  
  105.         while (m.find()) {  
  106.             mails.add(m.group());  
  107.         }  
  108.         return mails;  
  109.     }  
  110.   
  111. }  
 
Java代码  收藏代码
  1. package com.eehome.app.mail.utils;  
  2.   
  3. import java.text.SimpleDateFormat;  
  4. import java.util.Date;  
  5.   
  6. public class DateUtils {  
  7.   
  8.     public static final SimpleDateFormat sdf = new SimpleDateFormat(  
  9.             "yyyyMMddHHmmss");  
  10.   
  11.     /** 
  12.      * 获得当前时间组成的字符串,格式为yyyyMMddHHmmss 
  13.      * @return 
  14.      */  
  15.     public static String getTimeNow() {  
  16.         return sdf.format(new Date());  
  17.     }  
  18. }  

 

 

Java代码  收藏代码
  1. package com.eehome.app.mail.exception;  
  2.   
  3. public class FileIsNotExistException extends Exception {  
  4.   
  5.     /** 
  6.      * 文件不存在异常 
  7.      */  
  8.     private static final long serialVersionUID = -2545287258814097123L;  
  9.   
  10.     public FileIsNotExistException() {  
  11.         super();  
  12.     }  
  13.   
  14.     public FileIsNotExistException(String message, Throwable cause) {  
  15.         super(message, cause);  
  16.     }  
  17.   
  18.     public FileIsNotExistException(String message) {  
  19.         super(message);  
  20.     }  
  21.   
  22.     public FileIsNotExistException(Throwable cause) {  
  23.         super(cause);  
  24.     }  
  25.   
  26. }  

 

      接着为了写了一个shell脚本,把它作为一个后台执行的脚本,放到rc.local下,让其开机启动,这样IP邮件提醒的程序大功告成,呵呵。




谁有完整的代码  ?共享下 , 交流下 , 谢谢 。 




原创粉丝点击