VB.NET驗證郵件地址的合法性實現代碼

來源:互聯網
上載者:User
一、提出問題
  現在,對於使用者在Web頁面上或電話中給出的Email地址,我們越來越不敢肯定它是否真的有效。在今天這個垃圾郵件泛濫成災的年代,人們完全有理由捨不得輕易透露Email地址。
  
  另一方面,對於通過正規途徑得到的郵件地址,當我們將它用於合法的目的時,也常常要為郵件地址是否有效而煩惱,使用者可能有意或無意地寫錯地址,也可能由於長時間不訪問而導致郵箱失效。對於少量的郵件地址,也許可以手工驗證其合法性,例如發送測試email;但是,當郵件地址的數量達到數萬甚至更多時,手工驗證就不可能了,必須用專門的工具或自己編寫程式自動執行驗證。
  
  常規的驗證方法只從email地址的格式判斷其合法性,例如檢查它是否包含“@”和“.”符號。顯然,這種檢查是不充分的,郵件地址格式正確並不證明它一定有效。由於這個原因,一些網站採取了用email發送密碼、特殊資源的URL等辦法,或者要求使用者回複email,以此確保email地址的有效性。但是,這些辦法不見得任何時候都有效,例如,你可能不是從自己的網站上收集使用者email,而是通過第三者獲得。
  
  考慮到這些原因,驗證email地址合法性最根本的辦法是查詢郵件伺服器。本文將給出完成這一任務的完整VB.NET代碼。
  
   二、郵件伺服器之合法性
  對於任何郵件地址,判斷其合法性的第一步當然是看看它的格式是否正確,例如是否包含“@”和“.”符號,這方面的資料很多,甚至還有現成的控制項,所以本文不再贅述。我們的任務從判斷郵件地址的域是否合法開始,例如對於abc@sina.com.cn這個地址,首先判斷sina.com.cn的郵件伺服器是否有效。
  
  每一個域有一個MX記錄,即郵件交換器(Mail Exchanger)記錄,它指向該域內處理email的伺服器,我們只要查詢DNS伺服器即可獲得該資訊。Windows本身帶來的nslookup命令非常適合於完成該任務,例如,要尋找sina.com.cn的郵件伺服器,只需執行nslookup -type=mx sina.com.cn,其中-type=MX表示要尋找MX記錄,輸出結果如圖一所示。Windows的nslookup命令要安裝了TCP/IP協議後才可用,詳細說明可參見Windows協助。
    
  下面的GetMailServer函數封裝了調用Windows nslookup命令的操作,根據參數中指定的網域名稱返回郵件伺服器。
  
  Private Function GetMailServer(ByVal sDomain As String) As String
  Dim info As New ProcessStartInfo()
  Dim ns As Process
  "調用Windows的nslookup命令,尋找郵件伺服器
  info.UseShellExecute = False
  info.RedirectStandardInput = True
  info.RedirectStandardOutput = True
  info.FileName = "nslookup"
  info.CreateNoWindow = True
  "尋找類型為MX。關於nslookup的詳細說明,請參見
  "Windows協助
  info.Arguments = "-type=MX " + sDomain.ToUpper.Trim
  "啟動一個進行執行Windows的nslookup命令()
  ns = Process.Start(info)
  Dim sout As StreamReader
  sout = ns.StandardOutput
  " 利用Regex找出nslookup命令輸出結果中的郵件伺服器資訊
  Dim reg As Regex = New Regex("mail exchanger = (?[^\\\s]+)")
  Dim mailserver As String
  Dim response As String = ""
  Do While (sout.Peek() > -1)
  response = sout.ReadLine()
  Dim amatch As Match = reg.Match(response)
  If (amatch.Success) Then
  mailserver = amatch.Groups("server").Value
  Exit Do
  End If
  Loop
  Return mailserver
  End Function
  
   三、郵件地址之合法性
  只要郵件地址中指定的域合法,我們就可以串連郵件伺服器,試著發送一個email。如果郵件伺服器回答說該使用者非法或不存在,表明郵件地址無效。這一步的主要操作包括建立一個串連郵件伺服器的Socket,然後按照SMTP郵件傳輸協議的要求與伺服器通訊,完成郵件發送操作。關於SMTP協議的詳細說明,有興趣的讀者可參見SMTP規範(RFC 821):http://www.ietf.org/rfc/rfc821.txt。
  
  下面CheckEmail函數的輸入參數是一個郵件地址,函數的傳回值表示該地址是否合法。該函數有兩個數值可隨意調整:在發送郵件的過程中,我們要向對方的郵件伺服器提供一個合法的網域名稱以表明自己的身份,這裡選擇的是sina.com.cn;根據網路和對方郵件伺服器的忙閑程度,回應時間也會發生變化,這裡選擇的等待時間是3秒。當網路或對方伺服器非常忙時,減小等待時間會增加測試失敗的可能性。
  
  Public Function CheckEmail(ByVal sEmail As String) As Long
  
  Dim oStream As NetworkStream
  Dim sFrom As String "寄件者
  Dim sTo As String "收件者
  Dim sResponse As String "郵件伺服器的應答
  Dim Remote_Addr As String "寄件者的網域名稱
  Dim mserver As String "郵件伺服器
  Dim sText As String()
  
  sTo = "<" + sEmail + ">"
  " 從郵件地址分離出帳戶名稱和網域名稱
  sText = sEmail.Split(CType("@", Char))
  " 尋找該域的郵件伺服器
  mserver = GetMailServer(sText(1))
  "mserver為空白值表明尋找郵件伺服器失敗
  If mserver = "" Then
  Return 4
  Exit Function
  End If
  "寄件者地址的網域名稱必須合法
  Remote_Addr = "sina.com.cn"
  sFrom = "  "儘可能延遲建立對象的時間
  Dim oConnection As New TcpClient()
  Try
  "逾時時間
  oConnection.SendTimeout = 3000
  "串連SMTP連接埠
  oConnection.Connect(mserver, 25)
  "收集郵件伺服器的應答資訊
  oStream = oConnection.GetStream()
  sResponse = GetData(oStream)
  sResponse = SendData(oStream, "HELO " & Remote_Addr & vbCrLf)
  sResponse = SendData(oStream, "MAIL FROM: " & sFrom & vbCrLf)
  "如果對MAIL FROM指令有肯定的應答,
  "至少表明郵件地址的網域名稱正確
  If ValidResponse(sResponse) Then
  sResponse = SendData(oStream, "RCPT TO: " & sTo & vbCrLf)
  "如果對RCPT TO指令有肯定的應答
  "表明郵件伺服器已認可該地址
  If ValidResponse(sResponse) Then
  Return 1 "郵件地址有效
  Else
  Return 2 "只有網域名稱有效
  End If
  End If
  "結束與郵件伺服器的會話
  SendData(oStream, "QUIT" & vbCrLf)
  oConnection.Close()
  oStream = Nothing
  Catch
  Return 3 "錯誤!
  End Try
  End Function
  
  "擷取伺服器應答資料,並將其轉換為String
  Private Function GetData(ByRef oStream As NetworkStream) As String
  
  Dim bResponse(1024) As Byte
  Dim sResponse As String
  
  Dim lenStream As Integer = oStream.Read(bResponse, 0, 1024)
  If lenStream > 0 Then
  sResponse = Encoding.ASCII.GetString(bResponse, 0, 1024)
  End If
  Return sResponse
  End Function
  "向郵件伺服器發送資料
  Private Function SendData(ByRef oStream As NetworkStream, ByVal sToSend As String) As String
  Dim sResponse As String
  "將String轉換成Byte數組
  Dim bArray() As Byte = Encoding.ASCII.GetBytes(sToSend.ToCharArray)
  "發送資料
  oStream.Write(bArray, 0, bArray.Length())
  sResponse = GetData(oStream)
  "返回應答
  Return sResponse
  End Function
  
  "伺服器是否返回肯定的回答?
  Private Function ValidResponse(ByVal sResult As String) As Boolean
  Dim bResult As Boolean
  Dim iFirst As Integer
  If sResult.Length > 1 Then
  iFirst = CType(sResult.Substring(0, 1), Integer)
  "如果伺服器返回應答的第一個字元小於"3"
  "我們認為伺服器已認可剛才的操作
  If iFirst < 3 Then bResult = True
  End If
  Return bResult
  End Function
  
  CheckEmail函數的傳回值表示測試結果:1表示郵件地址合法,2表示只有網域名稱正確(可能是使用者的郵件帳戶無效),3表示出現了錯誤,4表示無法找到郵件伺服器。
  
   四、使用者介面
  以上我們完成了測試郵件地址是否合法的核心功能,這些函數可用於各種形式的應用程式,包括Web服務、Windows應用程式、控制項等,最多隻要修改一下聲明方式。為便於測試這些函數,下面我們要做一個Windows應用形式的簡單使用者介面。
  
  啟動VS.NET,選擇建立Visual Basic項目、Windows應用程式,如圖二,輸入項目名稱CheckMail以及儲存位置,點擊“確定”按鈕,VS.NET建立一個新的項目。
    
  從工具箱把一個文字標籤、一個輸入框和一個按鈕拖到VS.NET自動建立的表單上。將表單的TEXT屬性改為“Email地址測試”,文字標籤的TEXT屬性改為“郵件地址”,按鈕的TEXT屬性改為“Check!”,調整各個控制項的位置,使其看起來整齊美觀,如圖三。
    
  雙擊按鈕,輸入焦點擊按鈕時執行的Button1_Cli

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.