由于朋友在家使用ADSL拨号,想在单位随时也能访问家里的电脑。但是由于现在都是路由器自动拨号,而且也经常掉线。为了得到IP改变后的地址,我就做了一个很简单的程序,来检查IP是否发生变化,如果有变化就Email通知自己。
    其中利用了自己的资源做了个ip地址显示的服务(http://www.dircar.cn/ip.asp)。大家也可以使用ip138等服务,不过需要分析内容。
    原理比较简单,而且是用vbs来写的,直接运行也可以。添加到windows"任务计划"中做一个自动间隔运行的任务,就实现定时检查发通知啦。
    脚本做这种程序比较快而且维护、部署简单,但是也有一个问题会经常读写硬盘觉得不是很环保,用java或者C#做可以直接在内存中运用。唉真是很难十全十美,无所谓啦。
    开发和测试环境都是:windown2003,EditPlus
   
'check IP address changer robot for vbs
'
Author: wangchuyun@hotmail.com
'
Date: 2007-12-24 
'
自动检查出口IP是否改变,如果改变将通过email方式通知自己
'
由于发送邮件使用的指令都是针对自己的邮件服务器进行,如果换成
'
其他邮件服务商,需要进行一些调整。

Const SITE_IP= "http://www.dircar.cn/ip.asp"'我自己提供的客户端ip地址,简化分析html过程。
Const EMAIL_HOST = "mail.cliniclaw.cn"
Const USERNAME= "alert@cliniclaw.cn"
Const PASSWORD = "xxxx"'这个当然不能告诉大家啦

Const TO_MAIL = "alert@cliniclaw.cn"
Const FROM_MAIL = "alert@cliniclaw.cn"
Const TEMP_FILE = "c:\local_ip.tmp"
Const SLEEP_TIME = 1000 '模拟键盘输入终端的间隔时间,单位毫秒

Call DoWrok()

'程序入口
'
1、先获取ip地址
'
2、然后和上次保存的ip地址进行比较
'
3、如果ip地址发生了变化,发生邮件并记录最新的地址
Function DoWrok()
    
Dim ip,lastIp
    ip 
= GetURL(SITE_IP)
    lastIp 
= GetLastIP()

    
If InStr(ip,".")<1 Then
        
Exit Function 
    
End if    

    
If lastIP<>ip Then
        
'发送邮件
        Call SendMail(ip)
        
Call WriteLastIP(ip)
    
End If 
End Function

'读取本地文件,获取上次的ip地址信息
Function GetLastIP()
    
'On Error Resume Next
    Dim fs
    
Set fs = CreateObject("Scripting.FileSystemObject")
    
If fs.fileexists(TEMP_FILE) Then
        
Set ts = fs.OpenTextFile(TEMP_FILE,1,true)
        GetLastIP 
= ts.readall
        ts.close
        
Set ts = Nothing        
    
End If 
    
Set fs = nothing
End Function 

'将最新的ip地址保存到本地文件中
Function WriteLastIP(ip)
    
Dim fs
    
Set fs = CreateObject("Scripting.FileSystemObject")
    
Set ts = fs.OpenTextFile(TEMP_FILE,2,true)
    ts.write ip
    ts.close
    
Set ts = Nothing
    
Set fs = nothing
End Function 


'获取指定url的页面的源代码
Function GetUrl(url)
    
Dim IEObj
    
Set IEObj = CreateObject("internetexplorer.application")
    IEObj.navigate url
    
Do While IEObj.readystate < 4
        WScript.Sleep 
1000
    
Loop
    
    GetUrl 
= IEObj.Document.Body.InnerHTML
    
    IEObj.quit    
    
Set IEObj = Nothing
End Function 

'通过打开cmd窗口,利用模拟键盘输入方式使用
'
telnet登录邮件服务器,发送邮件
Function SendMail(ip)
    
Dim key
    
Set key=WScript.CreateObject("WScript.Shell")
    key.Run 
"cmd.exe"
    WScript.Sleep SLEEP_TIME
    key.SendKeys 
"telnet " & EMAIL_HOST & " 25{ENTER}"
    WScript.Sleep SLEEP_TIME
+1000 '怕有时网络连接慢,而多等待一会,根据实际情况来定

    key.SendKeys 
"ehlo hi{ENTER}"
    WScript.Sleep SLEEP_TIME
    key.SendKeys 
"auth login{ENTER}"
    WScript.Sleep SLEEP_TIME
    key.SendKeys  Base64Encode(USERNAME) 
& "{ENTER}"
    WScript.Sleep SLEEP_TIME
    key.SendKeys  Base64Encode(PASSWORD) 
& "{ENTER}"

    WScript.Sleep SLEEP_TIME
    key.SendKeys 
"mail from:<" & FROM_MAIL & ">{ENTER}"
    WScript.Sleep SLEEP_TIME
    key.SendKeys 
"rcpt to:<" & TO_MAIL & ">{ENTER}"
    WScript.Sleep SLEEP_TIME
    key.SendKeys 
"DATA{ENTER}"
    WScript.Sleep SLEEP_TIME
    
'key.SendKeys "{ENTER}"
    'WScript.Sleep SLEEP_TIME
    key.SendKeys "From: " & FROM_MAIL & "{ENTER}"    
    WScript.Sleep SLEEP_TIME
    key.SendKeys 
"To: " & TO_MAIL & "{ENTER}"
    WScript.Sleep SLEEP_TIME
    key.SendKeys 
"Date: " & Date & " " & Time & "{ENTER}"    
    WScript.Sleep SLEEP_TIME
    key.SendKeys 
"Subject: ip changes: " & ip & " (" & Date & " " & Time & "){ENTER}"   
    WScript.Sleep SLEEP_TIME
    key.SendKeys 
"{ENTER}"'正文开始,需要和subject空一行
    WScript.Sleep SLEEP_TIME
    key.SendKeys 
"now ip is " & ip & "{ENTER}"
    WScript.Sleep SLEEP_TIME
    key.SendKeys 
".{ENTER}"
    WScript.Sleep SLEEP_TIME
    key.SendKeys 
"quit{ENTER}"

    WScript.Sleep SLEEP_TIME
    key.SendKeys 
"{ENTER}exit{ENTER}"'退出cmd窗口
    Set key = Nothing
End Function 

'对字符串进行base64编码主要是email用户名和密码需要
Function Base64Encode(inData)
  
Const Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
  
Dim cOut, sOut, I

  
For I = 1 To Len(inData) Step 3
    
Dim nGroup, pOut, sGroup
    nGroup 
= &H10000 * Asc(Mid(inData, I, 1)) + _
      
&H100 * MyASC(Mid(inData, I + 11)) + MyASC(Mid(inData, I + 21))
    nGroup 
= Oct(nGroup)
    nGroup 
= String(8 - Len(nGroup), "0"& nGroup
    pOut 
= Mid(Base64, CLng("&o" & Mid(nGroup, 12)) + 11+ _
      
Mid(Base64, CLng("&o" & Mid(nGroup, 32)) + 11+ _
      
Mid(Base64, CLng("&o" & Mid(nGroup, 52)) + 11+ _
      
Mid(Base64, CLng("&o" & Mid(nGroup, 72)) + 11)
    sOut 
= sOut + pOut
  
Next
  
Select Case Len(inData) Mod 3
    
Case 1'8 bit final
      sOut = Left(sOut, Len(sOut) - 2+ "=="
    
Case 2'16 bit final
      sOut = Left(sOut, Len(sOut) - 1+ "="
  
End Select
  Base64Encode 
= sOut
End Function

Function MyASC(OneChar)
  
If OneChar = "" Then MyASC = 0 Else MyASC = Asc(OneChar)
End Function

在附上一个linux shell的版本,linux下就更简单啦
#check IP address changer robot.

ip
=`cat ip.asp`
tdate
=`date '+%Y-%m-%d %H:%M'`
echo 
$ip
sendmail
=0


if [ "$ip" == "" ]
then
  sendmail
=1
fi

wget 
-q http://www.dircar.cn/ip.asp
ip2
=`cat ip.asp`

if [ "$ip" != "$ip2" ]
then
  sendmail
=1
fi

if [ "$sendmail" == "1" ]
then
   echo 
$ip2 $tdate|mail -'ip change' wcy@cliniclaw.cn
fi

rm ip
.asp.* -rf

echo 
"ip=$ip";
echo 
"ip2=$ip2";
echo 
"sendmail=$sendmail";