`

编程实现邮件地址有效性检测

阅读更多

 

这个VB6COM组件提供了一项即时邮件查询的功能。它有效的避免了向一个不存在的账户发送邮件的情况。例如,在ASP页面里面检查用户输入的邮件地址是否正确,并避免在你的用户数据库里面存储相关的错误信息。

主要内容

工作原理

让我们首先来看一下这个组件是如何进行工作的。

首先给定一个E-mail地址(例如:someone@somewhere.com),然后它会执行如下的步骤:

1、 将用户名(someone)从域名(somewhere.com)中分离出来;

2、 在DNS(域名服务器)上进行查询:域名是否可用;

3、 如果DNS做出响应,它将在服务器上对MX进行查询(Mail Exchanger邮件交换服务器),并试着与在这个域中每一个MX建立会话,直到建立会话成功;

4、 通过使用SMTP协议,它使用VRFY命令和Mail handshake(HELO,MAILT FROM,RCPT TO)来验证用户名在该域中的存在;

5、 随后组件将返回测试的结果,并给出四种可能的结果:

l     “域”不存在。服务器做出否定响应。

l     “域”存在,但是无法查询用户名(见注释)。服务器做出部分确认响应。

l     “域”存在,但是用户名不存在。服务器做出否定响应。

l     “域”和用户名都存在。服务器做出完全确认响应。

注释:

如果“域”存在,但是MX(邮件交换服务器)并不存在于该域中(典型特征是二级域名由ISP掌握着),这样通过SMTP协议将会无效,应为那些服务器被指派去接受子域中的邮件,并且根本不会检查用户名。所以组建的程序设计,从这里跳出并返回出部分确认响应。

 

组件特征

l   在本地机器上查找DNS。所以必须保持计算机与互联网的连接以确保组建的正常工作

l   通过SimpleDNSROSolover组件(见Credits)发送DNS请求

l   使用UPD协议接收DNS响应

l   经过标准的winsock.ocx接口,建立SMTP会话

l   提供小型的可执行文件(编译为一个小于50kb的ActiveX DLL 动态连接库文件)

l   无任何用户接口,需要ActiveX组建支持的语言(例如,VBScript, ASP, VC++等等)

l   使用VB6.0 Service Pack 4(已测试) 环境下编译,当然也可以在以前的支持winsock.ocx的VB版本中编译(例如VB5.0)

安装方法

l   将压缩包释放到你选定的目录中;

l   将VfabEmailUtils.DLL拷贝到你的系统目录下:

对于Windows NT:C:\WINNT\SYSTEM32\

对于Windows 9 x:C:\WINDOWS\SYSTEM\

l   在注册表中注册组件:

在运行中输入:regsvr32 c:\winnt\system32\VfabEmailUtils.dll

l   重要提示:

为确保组件的正常运行,你必须安装Simple DNS Resolver v1.0(Emmanuel Kartmann’s)。相关信息,请看下面的Credits。

使用方法

l   创建一个组建的应用实例

l   加入属性:
EmailAddr
SmtpTimeOut
DNS Server Address
(仅限Windows9x)

l   调用CheckDomain 方法

l   测试Result属性,如果返回的结果不等于vfbInvalidDomain (1)则可以进行如下操作

l   调用CheckUserName 方法

l   然后测试Result属性来返回最终结果:
vfabNotVerify = 0
vfabInvalidDomain = 1
vfabValidDomain = 2
vfabValidDomainInvalidAccount = 3
vfabValidDomainValidAccount = 4

示例代码

dim oVfab

set oVfab=CreateObject("VFabEmailUtils.EmailCheck")              '创建对象

oVfab.EmailAddr = Request.Form("EMAIL")

'从ASP页面获得邮件地址以进行测试,

'并指派给该对象中的EmailAddr属性

oVfab.CheckDomain                                           '检查域是否存在

If oVfab.Result <> 1 Then

'如果存在则对用户名进行检测

oVfab.SmtpTimeOut = 10                                  '给该对象10秒钟的时间用来连接远程SMTP服务器

oVfab.CheckUserName                                    '尝试进行SMTP会话,测试用户名

End If

……                                                        '在这里可以用HTML格式显示会话纪录

oVfab.Clear                                                  '关闭连接, 清除日志, 恢复初始状态

组件文档

方法(表1):

名称

描述

CheckDomain()

检查邮件地址中的域名部分是否是有效的(存在的)域名

CheckUserName()

通过SMTP协议检查用户名是否是该域中的有效邮件账号

Clear()

在结束任务之后,关闭连接, 清除日志, 恢复初始状态

 

表1

属性(表2):

名称

类型

可读

可写

描述

EmailAddr

String

Yes

Yes

指定要检验的邮件地址

Result

Integer

Yes

No

从CheckDomain 和(或)CheckUserName 方法中获得处理结果

SmtpTimeOut

Integer

Yes

Yes

获得/设置Timeout(超时-秒计)等待SMTP连接

DnsServer

String

Yes

No

设置域名服务器的IP地址(Win9x中为必选项,Windows NT 中为可选项)

RealName

String

Yes

No

在CheckUserName()被执行后,如果SMTP服务器提供的话,获得用户的真实名称

DomainName

String

Yes

No

获得EmailAddr中的域名部分

UserName

String

Yes

No

获得EmailAddr中的用户名部分

Log(blnHTML)

String

Yes

No

检索会话日志(客户段与服务器的所有信息交换)如果可选参数被设为True,它将重新以HTML格式排列断点以便阅读。

SmtpServer

String

Yes

No

在域中获得完整地邮件交换服务器列表

 

表2

下面将对主要代码进行分析:

1、检测域名有效性:

Public Enum EmailVerifiedConst                     '创建一个枚举类型

……                                        '包含Result属性来返回最终结果

End Enum

 

Dim WithEVEnts oWinsock As Winsock                '创建一个包含事件的winsock对象,事件DataArrival在下面被定义

……

Public Sub CheckDomain()                           '声明定义CheckDomain方法

Dim oDNS As New SIMPLEDNSRESOLVERLib.SimpleDNSClient

'基于SIMPLEDNSRESOLVERLib建立对象oDNS

intPos = InStr(strEmailAddr, "@")                 '计算用户名的长度

If intPos = 0 Then                              '如果返回的结果是0

Err.Raise vbObjectError + 699, , "请指定有效的邮件地址!"

Exit Sub                                  '并从sub过程中跳出

End If

strUserName = Left(strEmailAddr, intPos - 1)        '获得用户名

strDomainName = Mid(strEmailAddr, intPos + 1)     '获得域名

……

oDNS.Separator = ", "                           '设置各地址之间的分隔符为”,”

intResult = EmailVerifiedConst.vfabInvalidDomain   '以枚举EmailVerifiedConst中的成员vfabInvalidDomain赋初值给intResult

strLog = strLog & "DNS   -> Query: MX records for " & strDomainName & vbCrLf        '进行日志记录

On Error Resume Next                           '发生错误继续

oDNS.GetEmailServers strDomainName, strSmtpServers '利用oDNS对象的GetMailServer方法给strSmtpServers赋值

If Err <> 0 Then                               

Err.Raise vbObjectError + 698, , Err.Description

End If

strLog = strLog & "DNS   <- " & strSmtpServers & vbCrLf '进行日志记录

If strSmtpServers <> "" Then

intResult = EmailVerifiedConst.vfabValidDomain    '以枚举EmailVerifiedConst中的成员vfabValidDomain赋值给intRe、sult

End If

End Sub

 

 

 

2、检测用户名的有效性:

Public Sub CheckUserName()                        '声明定义CheckUserName()方法

Dim strHost As String, i As Integer, intOldStep As Integer

i = 1                                         '在这里定义循环初始值,并以之为计数标志分割strSmtpServers

……

Do While True                                 '开始进行循环1

    strHost = Trim(LTrim(Token(strSmtpServers, ",", i)))

                                             '以”,”为分隔符分离字符串中的所有地址,使之各个独立,

'i是计数标志,下面对TOKEN()的声明定义中再作解释。

    If strHost = "" Then                         '如果发现在“,”后有空地址

        Exit Do                               '跳出循环

    End If

    If InStr(strHost, strDomainName) > 0 Then      '如果域名以前的部分不是空

        With oWinsock                        '设置oWinsock对象所使用的

            .Protocol = sckTCPProtocol          '协议为TCP

            .RemoteHost = strHost              '主机地址为strHost的值

            .RemotePort = 25                   '通信端口为25

            .Connect                         '并进行连接

            dblTimeOut = intSmtpTimeOut       '设置超时

            intStep = 1                        '将步骤索引intStep设为1

            Do While .State <> sckConnected     '如果套接字状态是非连接,开始循环2

                Sleep 100                    '延迟100ms

                DoEVEnts               '执行oWinsock包含事件DataArrival

                                            'DataArrival事件是用来对接收到的

                                            '做出反应用的;事件的定义在下面可以找到

                                            '该事件发生之后,会影响intStep、连接状态等

                dblTimeOut = dblTimeOut - 0.1 '超时减0.1秒

            Loop

            If .State <> sckConnected Then       '如果套接字状态是非连接

                Exit Sub                     '跳出函数体,结束对该方法的调用

            End If

            Do While True                    '循环3

                Select Case intStep             '依据步骤intStep进行判断

                ……

                Case 2

                    SendData "VRFY " & strUserName & "@" & strDomainName & vbCrLf '发送待确认请求

                Case 3

                    .Close                   '关闭套接字

                    Exit Do                  '并结束循环3

                ……

 

http://guoyang1982.blog.163.com/blog/static/61488351201048112520678/

http://wkf41068.iteye.com/blog/1596636

 

 

Java验证邮箱是否真实存在有效

 

要检测邮箱是否真实存在,必须了解两方面知识:
1. MX记录,winodws的nslookup命令。查看学习
2. SMTP协议,如何通过telnet发送邮件。查看学习

有个网站可以校验,http://verify-email.org/, 不过一小时只允许验证10次。

直接上代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import java.io.IOException;

import org.apache.commons.net.smtp.SMTPClient;
import org.apache.commons.net.smtp.SMTPReply;
import org.xbill.DNS.Lookup;
import org.xbill.DNS.Record;
import org.xbill.DNS.Type;

public class CheckEmailObj {
public static boolean checkEmail(String email) {
if (!email.matches("[\\w\\.\\-]+@([\\w\\-]+\\.)+[\\w\\-]+")) {
System.err.println("Format error");
return false;
}

String log = "";
String host = "";
String hostName = email.split("@")[1];
Record[] result = null;
SMTPClient client = new SMTPClient();

try {
// 查找MX记录
Lookup lookup = new Lookup(hostName, Type.MX);
lookup.run();
if (lookup.getResult() != Lookup.SUCCESSFUL) {
log += "找不到MX记录\n";
return false;
} else {
result = lookup.getAnswers();
}

// 连接到邮箱服务器
for (int i = 0; i < result.length; i++) {
host = result[i].getAdditionalName().toString();
client.connect(host);
if (!SMTPReply.isPositiveCompletion(client.getReplyCode())) {
client.disconnect();
continue;
} else {
log += "MX record about " + hostName + " exists.\n";
log += "Connection succeeded to " + host + "\n";
break;
}
}
log += client.getReplyString();

// HELO cyou-inc.com
client.login("cyou-inc.com");
log += ">HELO cyou-inc.com\n";
log += "=" + client.getReplyString();

// MAIL FROM: <zhaojinglun@cyou-inc.com>
client.setSender("zhaojinglun@cyou-inc.com");
log += ">MAIL FROM: <zhaojinglun@cyou-inc.com>\n";
log += "=" + client.getReplyString();

// RCPT TO: <$email>
client.addRecipient(email);
log += ">RCPT TO: <" + email + ">\n";
log += "=" + client.getReplyString();

if (250 == client.getReplyCode()) {
return true;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
client.disconnect();
} catch (IOException e) {
}
// 打印日志
System.err.println(log);
}
return false;
}

public static void main(String[] args) {
System.err.println("Outcome: "
+ CheckEmailObj.checkEmail("pandajj0703@gmail.com"));
}
}

需要的两个jar包:
http://www.dnsjava.org/download/  
http://apache.etoak.com /commons/net/binaries/commons-net-2.0.zip

执行结果:
MX record about gmail.com exists.
Connection succeeded to alt2.gmail-smtp-in.l.google.com.
220 mx.google.com ESMTP p37si6502151gvf.9
>HELO cyou-inc.com
=250 mx.google.com at your service
>MAIL FROM: <zhaojinglun@cyou-inc.com>
=250 2.1.0 OK p37si6502151gvf.9
>RCPT TO: <pandajj0703@gmail.com>
=250 2.1.5 OK p37si6502151gvf.9

Outcome: true


或者通过webservice实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;

public class CheckEmailWS {
public static boolean checkEmail(String email) {
String soapRequestData = ""
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">"
+ " <soap:Body>"
+ " <IsValidEmail xmlns=\"http://www.webservicex.net\">"
+ " <Email>" + email + "</Email>" + " </IsValidEmail>"
+ " </soap:Body>" + "</soap:Envelope>";

try {
URL u = new URL(
"http://www.webservicex.net/ValidateEmail.asmx?op=IsValidEmail");
URLConnection uc = u.openConnection();
uc.setDoOutput(true);
uc.setRequestProperty("Content-Type",
"application/soap+xml; charset=utf-8");
PrintWriter pw = new PrintWriter(uc.getOutputStream());
pw.println(soapRequestData);
pw.close();

DocumentBuilderFactory bf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = bf.newDocumentBuilder();
Document document = db.parse(uc.getInputStream());

String res = document.getElementsByTagName("IsValidEmailResult")
.item(0).getTextContent();

return Boolean.parseBoolean(res);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
Java代码   收藏代码
  1. 1.SMTP是工作在两种情况下:一是电子邮件从客户机传输到服务器;二是从某一个服务器传输到另一个  
  2.   服务器  
  3. 2.SMTP是个请求/响应协议,命令和响应都是基于ASCII文本,并以CR和LF符结束。响应包括一个表示返   
  4.   回状态的三位数字代码  
  5. 3.SMTP在TCP协议25号端口监听连接请求  
  6. 4.连接和发送过程  
  7. SMTP协议说复杂也不复杂(明明带有“简单”这个词嘛),说简单如果你懂得Sock。不过现在只是我们利用的就是第一条中说的,从客户机传输到服务器,当我们向一台服务器发送邮件时,邮件服务器会首先验证邮件发送地址是否真的存在于本服务器上。  
  8. 操作的步骤如下:  
  9. 连接服务器的25端口(如果没有邮件服务,连了也是白连)  
  10. 发送helo问候  
  11. 发送mail from命令,如果返回250表示正确可以,连接本服务器,否则则表示服务器需要发送人验证。  
  12. 发送rcpt to命令,如果返回250表示则Email存在  
  13. 发送quit命令,退出连接  


Java代码   收藏代码
  1. private static String[] removeInvalidateAddress(String[] addresses, String mailFrom)  
  2. {     
  3.     ArrayList<String> validateAddresses = new ArrayList<String>();  
  4.     String normalAddress = null;  
  5.     int code;  
  6.       
  7.     SMTPTransport smptTrans = null;  
  8.     if(StringUtils.isEmpty(mailFrom) || null == addresses)  
  9.     {  
  10.         return new String[0];  
  11.     }  
  12.     String sendCmd = "MAIL FROM:" + normalizeAddress(mailFrom);  
  13.     try  
  14.     {  
  15.     smptTrans = (SMTPTransport)sendSession.getTransport("smtp");  
  16.     smptTrans.connect();  
  17.     code = smptTrans.simpleCommand(sendCmd);  
  18.     if(code != 250 && code != 251)  
  19.     {  
  20.         logger.error("send from invalidate" + mailFrom);  
  21.     }  
  22.     else  
  23.     {  
  24.         for(String address : addresses)  
  25.         {  
  26.             normalAddress = normalizeAddress(address);  
  27.             String cmd = "RCPT TO:" + normalAddress;  
  28.     code = smptTrans.simpleCommand(cmd);  
  29.     if(code == 250 || code == 251)  
  30.     {  
  31.         validateAddresses.add(address);  
  32.     }  
  33.         }  
  34.     }  
  35.     }  
  36.     catch(MessagingException e)  
  37.     {  
  38.         logger.error("Validate mail address error. send from " + mailFrom, e);  
  39.     }  
  40.       
  41.     String[] result = validateAddresses.toArray(new String[validateAddresses.size()]);  
  42.     return result;  
  43. }  
  44.   
  45. private static String normalizeAddress(String addr)   
  46. {  
  47.     if ((!addr.startsWith("<")) && (!addr.endsWith(">")))  
  48.         return "<" + addr + ">";  
  49.     else  
  50.         return addr;  
  51. }  

 

http://blog.csdn.net/zapldy/article/details/3971579

 

http://blog.csdn.net/qq690197664/article/details/4453833

分享到:
评论

相关推荐

    精彩编程与编程技巧-检查电子邮件地址输入的有效性...

    通过本示例,我们不仅了解了如何使用 VBScript 和正则表达式来验证电子邮件地址的有效性,还学习了如何利用事件驱动编程模型来构建用户交互逻辑。这为开发者提供了一种实用的方法来确保用户输入的数据格式正确,从而...

    java检验用户邮箱是否真实有效(去邮箱服务器上检验)

    在验证邮箱有效性时,我们通常需要使用这两种协议与服务器建立连接。 为了确保数据传输的安全性,现代邮件服务器通常使用SSL(Secure Sockets Layer)或其升级版TLS(Transport Layer Security)进行加密。在...

    邮箱地址整理器

    该软件还具备地址有效性检测功能,能够检查邮箱地址格式的正确性,剔除无效或格式错误的邮箱,确保邮件能够准确送达目标用户。在群发邮件时,如果包含大量无效邮箱,可能导致邮件发送失败,甚至被邮件服务商视为垃圾...

    C#检测邮箱地址是否存在源码

    此外,这种方法并不能100%确保邮箱的准确性,因为一些邮件服务器可能允许连接但不保证邮箱的有效性。 在实际应用中,我们通常会结合这两种方法,先做格式验证,再进行MX记录查询。但为了用户体验和避免滥用,往往...

    VB.net开发的Email邮箱地址检验程序源代码.rar

    VB.NET提供了System.Text.RegularExpressions命名空间,通过Regex类我们可以创建和执行正则表达式模式来检查电子邮件地址的有效性。有效的电子邮件地址通常应遵循RFC 5322标准,但实际应用中我们可能使用更简化的...

    邮件地址检查器C#源码

    【邮件地址检查器C#源码】是一款基于C#编程语言开发的应用程序,主要用于验证电子邮件地址的有效性。在软件开发中,确保用户输入的电子邮件地址符合标准格式是至关重要的,因为这关系到邮件发送的成功率以及用户体验...

    JS输入框邮箱地址验证代码

    本文主要介绍电子邮件地址验证相关的正则表达式以及如何在JavaScript中实现邮箱地址的有效性验证。正则表达式是进行模式匹配的强大工具,在Web开发中常用于表单验证、数据清洗等场景。通过本文的学习,你将能够掌握...

    不良邮件内容信息检测在Linux内核中的实现.pdf

    总结来说,"不良邮件内容信息检测在Linux内核中的实现"是一项旨在提高邮件服务安全性和效率的技术,它通过内核级别的优化,利用多CPU并行处理和专用缓存,实现了高效的内容检测,为现代网络环境下的邮件服务提供了...

    自动检测邮箱登陆

    如果连接成功,可以发送测试邮件并确认接收,进一步验证邮箱的有效性。 6. **异常处理**:当连接失败或验证出错时,应捕获并处理相应的异常,如`AuthenticationFailedException`、`MessagingException`等,为用户...

    winform高仿163邮箱收件人输入方式实现

    为了保证输入的有效性,需要对输入的邮箱地址进行格式验证,确保它们符合电子邮件的通用格式。这可以通过正则表达式完成。 6. **用户体验优化**: 类似163邮箱的设计,可能还包含了一些用户体验优化的细节,比如...

    labview编程实现温度数据的采集

    9. **程序结构**:理解并应用LabVIEW的模块化编程概念,如子VI(虚拟仪器),可以提高代码复用性和维护性。将各个功能封装为独立的子VI,如数据采集、数据处理和用户界面,可以更有效地组织代码。 10. **版本控制与...

    营口山鹰消防主机调试编程软件 营口新山鹰消防主机调试编程软件

    这意味着无论用户手头的是哪一类型的设备,都能够通过这款软件进行有效的调试和编程。 2. **调试功能**:调试功能是软件的核心,它允许用户检查并修正消防主机的硬件和软件问题,包括但不限于检测设备连接、测试...

    论文研究-多层次邮件蠕虫检测系统的设计 .pdf

    国际上,研究人员讨论了蠕虫技术的发展趋势、提出了衡量防范技术有效性的参数,并通过异常网络流量检测试图实现对蠕虫的防范。同时,国外学术界提出了利用可编程逻辑设备对抗蠕虫等技术,以及利用蠕虫对抗蠕虫的思想...

    商业编程-源码-用户注册无刷新检测源码.zip

    "商业编程-源码-用户注册无刷新检测源码.zip" 文件很可能包含了一套实现此功能的完整源代码,可以帮助开发者理解并应用到自己的项目中。下面我们将深入探讨无刷新检测以及在用户注册中的应用。 无刷新检测,也称为...

    邮件检测程序

    邮件检测程序需要理解和实现SMTP协议来接收、发送和验证邮件。 2. **POP3/IMAP协议**:邮局协议(POP3)和互联网消息访问协议(IMAP)用于从邮件服务器下载邮件。邮件检测程序可能需要这些协议来检查用户的收件箱。...

    编译原理——邮件地址词法分析

    在这个特定的场景中,我们关注的是“邮件地址词法分析”,这是一个编译原理的应用,用于解析和验证邮件地址的有效性。词法分析是编译器设计的首要步骤,其目的是将源代码分解成一系列有意义的单元,称为标记(token...

    邮箱检测器 MDM邮箱检测器 v1.0

    它提供了对网易、搜狐和新浪等主流邮箱服务的账号密码的有效性检测功能,帮助用户筛选出活跃且可用的邮箱账户,避免无效邮件的发送,提高邮件营销的效率。 该软件的核心知识点包括: 1. **邮箱验证机制**:MDM邮箱...

    Check_Email_Demo.rar

    《基于VS2008 MFC的邮件地址有效性检测工具详解》 在信息技术领域,电子邮件作为重要的通信方式,其正确性和有效性是不容忽视的。本文将深入探讨一个使用Visual Studio 2008(VS2008)下的Microsoft Foundation ...

    网络编程聊天程序

    在网络编程中,TCP被广泛应用于需要高可靠性的场景,如文件传输、电子邮件、Web浏览等。 #### 1.2 Socket编程概述 Socket是网络编程中的一种抽象概念,用来描述IP地址和端口,为应用程序提供一种通信机制。在TCP/IP...

    基于Socket网络编程的服务器远程监控系统的实现.doc

    - **告警通知**:当检测到异常情况时,能够通过邮件、短信等方式即时通知管理员。 - **日志记录**:记录所有监控数据和操作记录,便于后续分析和审计。 系统架构采用了客户端/服务器(C/S)模式,其中: - **客户端...

Global site tag (gtag.js) - Google Analytics