如何验证 Email 地址:SMTP 协议入门教程
http://www.ruanyifeng.com/blog/2017/06/smtp-protocol.html
作者: 阮一峰
日期: 2017年6月25日
Email 是最常用的用户识别手段。
开发者常常需要验证邮箱的真实性。一般的方法是,注册时向该邮箱发出一封验证邮件,要求用户点击邮件里面的链接。
但是很多时候(比如要搞邮件营销时),拿到的是成千上万现成的 Email 地址,不可能通过回复确认真实性,这时该怎么办呢?
答案就是使用 SMTP 协议。本文将介绍如何通过该协议验证邮箱的真假。
另外,结尾处还有一则移动端 H5 开发的培训消息,欢迎关注。
一、SMTP 协议简介
SMTP 是"简单邮件传输协议"(Simple Mail Transfer Protocol)的缩写,基于 TCP 协议,用来发送电子邮件。
只要运行了该协议的服务器端(daemon),当前服务器就变为邮件服务器,可以接收电子邮件。
验证 Email 邮箱的基本思路如下。
- 找到邮箱所在域名的 SMTP 服务器
- 连接该服务器
- 询问有没有该邮箱
- 如果服务器返回 250 或 251 状态码,邮箱就是真的;如果返回 5xx(500~599),就是假的。
注意,即使服务器确认邮箱是真的, 也不代表邮件一定会发送到该邮箱,更不代表用户一定会读到该邮件。
二、查找域名的 MX 记录
下面通过一个例子,演示如何验证test@gmail.com
这个邮箱。
首先,需要查找gmail.com
的 MX 记录。它指向真正处理邮件的那台服务器。
$ nslookup
>
输入nslookup
命令后,会提示一个大于号,表示等待用户进一步输入。
> set q=mx
> gmail.com
上面代码中,set q=mx
设定查询的是 MX 记录,第二行输入要查找的域名,结果返回了5条 MX 记录。
Server: 192.168.1.1
Address: 192.168.1.1#53 Non-authoritative answer:
gmail.com mail exchanger = 20 alt2.gmail-smtp-in.l.google.com.
gmail.com mail exchanger = 30 alt3.gmail-smtp-in.l.google.com.
gmail.com mail exchanger = 10 alt1.gmail-smtp-in.l.google.com.
gmail.com mail exchanger = 5 gmail-smtp-in.l.google.com.
gmail.com mail exchanger = 40 alt4.gmail-smtp-in.l.google.com.
gmail.com
是很大的邮件服务商,所以会有多条记录,一般的域名只有一条。如果这一步查不到 MX 记录,该邮箱肯定是假的。
除了自己执行nslookup
,也可以使用线上服务(1,2,3)。更多 DNS 的介绍,请参考《DNS 原理入门》。
三、建立 TCP 连接
知道了邮件服务器的地址,就可以与它建立 TCP 连接了。SMTP 协议的默认端口是25。使用 Telnet 或 Netcat 命令,都可以连接该端口。
$ telnet gmail-smtp-in.l.google.com 25
# 或者
$ nc gmail-smtp-in.l.google.com 25
服务器返回220
状态码,就表示连接成功。
220 mx.google.com ESMTP f14si7006176pln.607 - gsmtp
接下来,就可以使用 SMTP 协议的各种命令与邮件服务器交互了。
四、HELO 命令和 EHLO 命令
SMTP 协议规定,连接成功后,必须向邮件服务器提供连接的域名,也就是邮件将从哪台服务器发来。
假定从mail@example.com
向test@gmail.com
发送邮件,这里要提供的域名就是example.com
。
HELO exampl.com
邮件服务器返回状态码250
,表示响应成功。
250 mx.google.com at your service
不过,HELO
命令现在比较少用,一般都使用EHLO
命令。
EHLO example.com
邮件服务器收到EHLO
命令以后,不仅会返回250
状态码,还会返回自己支持的各种扩展的列表。
250-mx.google.com at your service, [114.84.160.153]
250-SIZE 157286400
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8
五、MAIL FROM 命令
然后,连接者要使用MAIL FROM
命令,向邮件服务器提供邮件的来源邮箱。
MAIL FROM:<mail@example.com>
上面代码表示,连接者将从mail@example.com
向邮件服务器发送邮件。邮件服务器返回250
状态码,表示响应成功。
250 2.1.0 OK h10si3194349otb.59 - gsmtp
SMTP 是一个很简单的协议,本身没有规定如何验证邮件的来源,也就是说,不验证邮件是否真的从mail@example.com
发来,所以导致了后来垃圾邮件泛滥。为了控制垃圾邮件,许多邮件服务器会用自己的方法验证邮件地址,下面就是其中的一些方法。
- example.com 是否有 MX 记录
- example.com 是否可以 Ping 通
- 是否存在 postmaster@example.com 这个邮箱
- 发起连接的 IP 地址是否在黑名单之中
- IP 地址的反向 DNS 解析,是否指向一个邮件服务器
六、RCPT TO 命令
最后一步就是使用RCPT TO
命令,验证邮件地址是否存在。
RCPT TO:<test@gmail.com>
邮件服务器返回了550
状态码,表示该 Email 地址不存在。
550-5.1.1 The email account that you tried to reach does not exist. Please try
550-5.1.1 double-checking the recipient's email address for typos or
550-5.1.1 unnecessary spaces. Learn more at
550 5.1.1 https://support.google.com/mail/?p=NoSuchUser p34si3372771otp.228 - gsmtp
如果查询的是一个真实的 Email 地址,邮件服务器就会返回250
状态码。
RCPT TO:<yifeng.ruan@gmail.com>
250 2.1.5 OK p34si3372771otp.228 - gsmtp
一般来说,状态码 250 和 251 都表示邮箱存在,状态码 5xx 表示不存在,其他状态码(主要是 4xx)则代表无法确认。
RCPT TO:<xxx@censored.pl>
451 Temporary local problem - please try later
验证完成后,使用QUIT
命令关闭 TCP 连接。
QUIT
221 2.0.0 closing connection p34si3372771otp.228 - gsmtp
七、参考链接
(正文完)
如何验证 Email 地址:SMTP 协议入门教程的更多相关文章
- javascript使用正则表达式验证Email地址
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- WCF入门教程(四)通过Host代码方式来承载服务 一个WCF使用TCP协议进行通协的例子 jquery ajax调用WCF,采用System.ServiceModel.WebHttpBinding System.ServiceModel.WSHttpBinding协议 学习WCF笔记之二 无废话WCF入门教程一[什么是WCF]
WCF入门教程(四)通过Host代码方式来承载服务 Posted on 2014-05-15 13:03 停留的风 阅读(7681) 评论(0) 编辑 收藏 WCF入门教程(四)通过Host代码方式来 ...
- python3之模块SMTP协议客户端与email邮件MIME对象
转载自https://www.cnblogs.com/zhangxinqi/p/9113859.html 阅读目录 1.smtplib模块的常用类与方法 2.处理邮件MIME 3.实例 (1)使用HT ...
- 用http.get()简单实现网络验证防止客户不给尾款_电脑计算机编程入门教程自学
首发于:用http.get()简单实现网络验证防止客户不给尾款_电脑计算机编程入门教程自学 http://jianma123.com/viewthread.aardio?threadid=428 给软 ...
- 【OpenLayers】入门教程地址
[OpenLayers]入门教程地址: 点击进入 http://anzhihun.coding.me/ol3-primer/index.html 简书地址 : http://www.jians ...
- Email地址验证
<script>function validateForm(){ var x=document.forms["myForm"]["email"].v ...
- php中的curl使用入门教程和常见用法实例
摘要: [目录] php中的curl使用入门教程和常见用法实例 一.curl的优势 二.curl的简单使用步骤 三.错误处理 四.获取curl请求的具体信息 五.使用curl发送post请求 六.文件 ...
- 基于公网smtp协议实现邮件服务器
刚开始做邮件服务器开发,一切都是茫然的.在书上网上都很难找到一套完整的邮件服务器开发教程.在个人的摸索中碰到了很多蛋疼得问题.现终于完成了,将我的开发经验分享给大家. 开发环境:vs2012 mfc ...
- 《JavaScript语言入门教程》记录整理:运算符、语法和标准库
目录 运算符 算数运算符 比较运算符 布尔运算符 二进制位运算符 void和逗号运算符 运算顺序 语法 数据类型的转换 错误处理机制 编程风格 console对象和控制台 标准库 Object对象 属 ...
随机推荐
- CentOS6.8下安装MySQL5.6
一:卸载旧版本 使用下面的命令检查是否安装有MySQL Server rpm -qa | grep mysql 有的话通过下面的命令来卸载掉 rpm -e mysql //普通删除模式 rpm -e ...
- R语言绘制花瓣图flower plot
R语言中有很多现成的R包,可以绘制venn图,但是最多支持5组,当组别数大于5时,venn图即使能够画出来,看上去也非常复杂,不够直观: 在实际的数据分析中,组别大于5的情况还是经常遇到的,这是就可以 ...
- C# listview控件右击导出数据到txt文本
private void 导出成功点击ToolStripMenuItem_Click(object sender, EventArgs e) { ) { MessageBox.Show("列 ...
- memcached能获取所有的key吗
memcached能获取所有的key吗 Memcache 查看列出所有key方法 Memcached中获取所有的key 特别要注意:memcached保存的值需要序列化,否则是无法保存的,而且是不会报 ...
- HDU 5414 CRB and String (2015年多校比赛第10场)
1.题目描写叙述:点击打开链接 2.解题思路:本题要求推断字符串s是否能通过加入若干个字符得到字符串t. 首先,能够知道,s必须是t的一个子串(注意:不是连续子串). 第二.因为插入的新字符和它前面的 ...
- 通过tarball形式安装HBASE Cluster(CDH5.0.2)——如何配置分布式集群中的zookeeper
集群安装总览参见这里 Zookeeper的配置 1,/etc/profile中加入zk的路径设置,见上面背景说明. 2,进入~/zk/conf目录,复制zoo_sample.cfg为zoo.cfg v ...
- glibc中fork系统调用传参
因为想跟踪下在新建进程时,如何处理新建进程的vruntime,所以跟踪了下fork. 以glic-2.17中ARM为例(unicore架构的没找到),实际上通过寄存器向系统调用传递的参数为: r7: ...
- mysql中explain
1.select_type: /* select_type 使用 SIMPLE */explain select * from tb_shop_order where id='201603292570 ...
- Java并发:多线程和java.util.concurrent并发包总结
多线程和java.util.concurrent并发包 转载:
- GCD (Grand Central Dispatch) 笔记
GCD (Grand Central Dispatch) 是Apple公司开发的一种技术,它旨在优化多核环境中的并发操作并取代传统多线程的编程模式. 在Mac OS X 10.6和IOS 4.0之后开 ...