VB.NET编程验证邮件地址的合法性
2006-09-30 14:30:21 作者: lkmplwxf 来源: 浏览次数: 63 文字大小:【 大】【 中】【 小】 评分等级:0
一、提出问题 现在,对于用户在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 ' 利用正则表达式找出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_Click过程。
Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click '如邮件地址为空,返回 If TextBox1.Text = "" Then Exit Sub End If '这里可插入检查邮件地址格式的代码, '如邮件地址是否包含“@”和“.”符号等 select Case CheckEmail(TextBox1.Text) Case 1 MsgBox("1=邮件地址合法") Case 2 MsgBox("2=域名正确") Case 3 MsgBox("3=出现错误!") Case 4 MsgBox("4=不能找到邮件服务器") End Select End Sub | 按Ctrl+Home键将光标移到代码编辑窗口的顶部,加入下列Imports语句:
Imports System.IO Imports System.Text.RegularExpressions Imports System.Net.Sockets Imports System.Text | 在Button1_Click过程的后面,依次输入前文给出的几个核心函数。完成后,点击工具栏上的启动按钮,VS.NET开始编译程序,接着启动程序。程序运行界面如图四所示。输入邮件地址后,点击Check!按钮,程序开始检查该email地址是否有效。
图四 | 根据测试结果的不同,程序的提示信息也不同。例如,如果邮件帐户不合法,但域名合法,程序显示出图五的对话框。
图五 |
|
本文作者:佚名 来源:http://www.codepub.com
CIO之家 www.ciozj.com 微信公众号:imciow
免责声明:本站转载此文章旨在分享信息,不代表对其内容的完全认同。文章来源已尽可能注明,若涉及版权问题,请及时与我们联系,我们将积极配合处理。同时,我们无法对文章内容的真实性、准确性及完整性进行完全保证,对于因文章内容而产生的任何后果,本账号不承担法律责任。转载仅出于传播目的,读者应自行对内容进行核实与判断。请谨慎参考文章信息,一切责任由读者自行承担。
延伸阅读