项目中需要用到smtp协议来发送邮件告警,后端的技术栈主要是Java和C++,Java项目里直接在网上找的现成的类完美实现,163邮箱,腾讯邮箱和阿里邮箱均测试通过,不幸的是C++的项目也需要使用smtp协议来发送邮件,惯例先度娘,CSDN逛了一圈,例程也不少但是每个下边留言都有这样和那样的问题,copy过来直接运行,163邮箱完美测试通过,我们用的钉钉全家桶,测试钉钉邮箱时发现不能发送邮件,认证都有问题。好吧,还是先老老实实的学习遍SMTP协议吧

WireShark抓取一次完整的邮件交互过程(关闭ssl):

流程如下:

第一步:发送EHLO指令,申明身份,表示自己身份需要验证,注意这部分需要通过Telnet验证一下,是user@example.com还是user,否则会出错。

第二步:发送AUTH LOGIN指令,登录邮箱,这一部分一般要用base64加密。

第三步:发送MAIL指令,这个命令用来开始传送邮件,它的后面跟随发件方邮件地址(返回邮件地址)。它也用来当邮件无法送达时,发送失败通知。为保证邮件的成功发送,发件方的地址应是被对方或中间转发方同意接受的。这个命令会清空有关的缓冲区,为新的邮件做准备。

第四步:发送RCPT指令,这个命令告诉收件方收件人的邮箱。当有多个收件人时,需要多次使用该命令RCPT TO,每次只能指明一个人。如果接收方服务器不同意转发这个地址的邮件,它必须报550错误代码通知发件方。如果服务器同意转发,它要更改邮件发送路径,把最开始的目的地(该服务器)换成下一个服务器。

第五步:发送DATA指令,收件方把该命令之后的数据作为发送的数据。数据被加入数据缓冲区中,以单独一行是”.”的行结束数据。结束行对于接收方同时意味立即开始缓冲区内的数据传送,传送结束后清空缓冲区。如果传送接受,接收方回复OK。

第六步:发送QUIT指令,SMTP要求接收放必须回答OK,然后中断传输;在收到这个命令并回答OK前,收件方不得中断连接,即使传输出现错误。发件方在发出这个命令并收到OK答复前,也不得中断连接。

分析:

掌握了基本的流程和抓取了数据包,只要C++也按照这种数据格式发送即可,认证不通过,首先怀疑用户名和密码传输的数据有问题,抓取C++发送的数据包,果然User数据BASE64的值不一样,Pass的值是一样的,解Base64后发现一个是user@example.com,一个是user,显然问题出在这,163邮箱要求是user,钉钉邮箱要求是user@example.com,改正后认证成功,接着发送邮件也OK,完事大吉,然而。。。一周后项目完成交给测试人员,告诉我告警邮件发不过来,怎么可能,运行工程,打脸了,只能发送一次,接着就发不出去邮件了,难道钉钉给屏蔽了,Java测试了下,没问题,好吧,继续抓包,认证是没问题的,发送过去就是收不到。

Java发送抓取的DATA数据部分如下:

C++发送抓取的DATA数据部分如下:

很明显差别太大了,From,To的格式不对,Content-Type也不对,但是明显差别的是少了Message-ID字段,所以重点先分析Message-ID,又抓取了多次比对后每次的Message-ID都是不同的,怀疑这给C++只能发送一次成功有关系,C++中增加了如下代码:

    email = "From: ";
    email += user;
    email += "\r\n";     email += "To: ";
    email += targetAddr;
    email += "\r\n";     //新增
    email += "Message-ID: ";
    email += “1”;
    email += "\r\n";     email += "Subject: ";
    email += title;
    email += "\r\n";     email += "MIME-Version: 1.0";
    email += "\r\n";     email += "Content-Type: multipart/mixed;boundary=qwertyuiop";
    email += "\r\n";
    email += "\r\n";

运行果然成功了,但是在运行又不成功了,把Message-ID值改为2又成功了,问题果然出在这里,大功告成,最终Message-ID改为:机器名+随机数。

总结:

WireShark是个很好的工具,善于使用它分析网络传输协议,抓包能够说明一切,让问题一目了然。

Java架构师之路,一个汇聚十万技术人的圈子,让学习之路更有趣!

一次邮件发送协议SMTP问题排查的更多相关文章

  1. 45.简单邮件传输协议 SMTP

    一丶简单邮件传输协议 简单邮件传输协议 简单邮件传输协议 SMTP smtplib 模块:(在 Python3版本中,可以通过 SMTP协议发送邮件的模块常为 smtplib, 并且这个模块属于内置模 ...

  2. 3.13 练习题4:邮件发送(smtp)

    3.13 练习题4:邮件发送(smtp) 前言本篇总结了QQ邮箱和163邮箱发送邮件,邮件包含html中文和附件,可以发给多个收件人,专治各种不行,总之看完这篇麻麻再也不用担心我的邮件收不到了.以下代 ...

  3. POP3是收邮件的协议,SMTP是发邮件的协议,IMAP是一种邮箱通信协议。

    我也是第一次接触这种服务,是因为我自己在做一个小小的自动推送天气情况到自己邮箱.所以才碰到这个的/ 看一下标题,我们可以先这样理解. POP3(Post Office Protocol - Versi ...

  4. 简单邮件传输协议SMTP

    1.SMTP是由源地址到目的地址传送邮件的一组规则,用来控制信件的中转方式. 2.SMTP服务器是遵循SMTP协议的发送邮件服务器,用来发送或者中转发出的邮件,客户端通过SMTP命令与SMTP服务器进 ...

  5. 发送邮件(遵循smtp协议即简单的邮件发送协议)

    HandleSendEmail.aspx逻辑 protected void Page_Load(object sender,EventArgs e) { foreach(var item in Req ...

  6. 理解邮件传输协议(SMTP、POP3、IMAP、MIME)

    http://blog.csdn.net/xyang81/article/details/7672745 电子邮件需要在邮件客户端和邮件服务器之间,以及两个邮件服务器之间进行传递,就必须遵循一定的规则 ...

  7. C# SMTP邮件发送 分类: C# 2014-07-13 19:10 334人阅读 评论(1) 收藏

    邮件发送在网站应用程序中经常会用到,包括您现在看到的博客,在添加评论后,系统会自动发送邮件通知到我邮箱的,把系统发送邮件的功能整理了下,做了一个客户端Demo,希望对有需要的童鞋有所帮助: 核心代码: ...

  8. C# SMTP邮件发送 分类: C# 2014-07-13 19:10 333人阅读 评论(1) 收藏

    邮件发送在网站应用程序中经常会用到,包括您现在看到的博客,在添加评论后,系统会自动发送邮件通知到我邮箱的,把系统发送邮件的功能整理了下,做了一个客户端Demo,希望对有需要的童鞋有所帮助: 核心代码: ...

  9. C# SMTP邮件发送程序

    邮件发送在网站应用程序中经常会用到,包括您现在看到的博客,在添加评论后,系统会自动发送邮件通知到我邮箱的,把系统发送邮件的功能整理了下,做了一个客户端Demo,希望对有需要的童鞋有所帮助: 核心代码: ...

随机推荐

  1. polymer-developer guide-registration and lifecycle

    注册和声明周期 my = Polymer({ is: "proto-element", created: function() { this.innerHTML = 'create ...

  2. 【转载】45个设计师们不常见的html5和css3漂亮模板

    对于Web开发人员来说,当他们需要创建一个非常时尚和新潮的CSS3和HTML5网站时需要非常专业的水准.html5和css3的结合能够做出非同寻常的网站效果..所以,今天,我推荐给大家45个免费的时尚 ...

  3. HTML5、CSS3与响应式Web设计入门(2)

    HTML5的宽泛含义开拓了Web开发的视野,增加了开发方案的多样性,同时也带给很多Web开发者不小的困惑,就是HTML5在涉及到Web某个应用领 域的开发时,到底代表了什么?本篇文章的目的就在于跟大伙 ...

  4. 如何为SharePoint文档库、文件夹、文件单独设置权限

    在这里使用截图的方式简单描述两个问题:设置SharePoint Server文档库权限和文档库中的文件夹权限 一.设置SharePoint Server文档库权限 Figure 1 - 打开文档库后, ...

  5. XML--将XML中数据提取出转换成表2

    DECLARE @xml XMLSET @xml = '<Students>    <Student  id="1001" name = "xu&quo ...

  6. PHP设计超级好用的文件上传处理类一 (37)

    <?php class FileUpload { private $filepath; //指定上传文件保存的路径 private $allowtype=array('gif', 'jpg', ...

  7. 【ocp-12c】最新Oracle OCP-071考试题库(42题)

    42.(9-1)choose the best answer: Which statement is true about the Oracle SQL, DELETE and TRUNCATE st ...

  8. 【12c OCP】CUUG OCP认证071考试原题解析(33)

    33.choose the best answer View the Exhibit and examine the structure of the ORDER_ITEMS table. Exami ...

  9. “全栈2019”Java多线程第十六章:同步synchronized关键字详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  10. “全栈2019”Java第四章:创建第一个Java程序

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...