由于朋友在家使用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 + 1, 1)) + MyASC(Mid(inData, I + 2, 1))
    nGroup = Oct(nGroup)
    nGroup = String(8 - Len(nGroup), "0") & nGroup
    pOut = Mid(Base64, CLng("&o" & Mid(nGroup, 1, 2)) + 1, 1) + _
      Mid(Base64, CLng("&o" & Mid(nGroup, 3, 2)) + 1, 1) + _
      Mid(Base64, CLng("&o" & Mid(nGroup, 5, 2)) + 1, 1) + _
      Mid(Base64, CLng("&o" & Mid(nGroup, 7, 2)) + 1, 1)
    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 -s 'ip change' wcy@cliniclaw.cn
fi
![]()
rm ip.asp.* -rf
![]()
echo "ip=$ip";
echo "ip2=$ip2";
echo "sendmail=$sendmail";
 
其中利用了自己的资源做了个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 + 1, 1)) + MyASC(Mid(inData, I + 2, 1))
    nGroup = Oct(nGroup)
    nGroup = String(8 - Len(nGroup), "0") & nGroup
    pOut = Mid(Base64, CLng("&o" & Mid(nGroup, 1, 2)) + 1, 1) + _
      Mid(Base64, CLng("&o" & Mid(nGroup, 3, 2)) + 1, 1) + _
      Mid(Base64, CLng("&o" & Mid(nGroup, 5, 2)) + 1, 1) + _
      Mid(Base64, CLng("&o" & Mid(nGroup, 7, 2)) + 1, 1)
    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 -s 'ip change' wcy@cliniclaw.cn
fi
rm ip.asp.* -rf
echo "ip=$ip";
echo "ip2=$ip2";
echo "sendmail=$sendmail";