1.     SMTP 常用命令简介

1). SMTP 常用命令

HELO/EHLO 向服务器标识用户身份

MAIL 初始化邮件传输

mail from:

RCPT 标识单个的邮件接收人;常在MAIL 命令后面

可有多个rcpt to:

DATA 在单个或多个RCPT 命令后,表示所有的邮件接收人已标识,并初始化数据传输,以. 结束。

VRFY 用于验证指定的用户/ 邮箱是否存在;由于安全方面的原因,服务器常禁止此命令

EXPN 验证给定的邮箱列表是否存在,扩充邮箱列表,也常被禁用

HELP 查询服务器支持什么命令

NOOP 无操作,服务器应响应OK

QUIT 结束会话

RSET 重置会话,当前传输被取消

如你对SMTP 命令不了解,可以用telnet 命令登陆到smtp 服务器用help 命令进行查看:

220 tdcsw.maintek.corpnet.asus ESMTP Sendmail 8.13.8/8.13.8; Sat, 9 Jan 2010 10:
45:09 +0800
help
214-2.0.0 This is sendmail
214-2.0.0 Topics:
214-2.0.0       HELO    EHLO    MAIL    RCPT    DATA
214-2.0.0       RSET    NOOP    QUIT    HELP    VRFY
214-2.0.0       EXPN    VERB    ETRN    DSN     AUTH
214-2.0.0       STARTTLS
214-2.0.0 For more info use "HELP <topic>".
214-2.0.0 To report bugs in the implementation see
214-2.0.0       http://www.sendmail.org/email-addresses.html
214-2.0.0 For local information send email to Postmaster at your site.
214 2.0.0 End of HELP info

2).SMTP 返回码含义

*   邮件服务返回代码含义

*   500   格式错误,命令不可识别(此错误也包括命令行过长)

*   501   参数格式错误

*   502   命令不可实现

*   503   错误的命令序列

*   504   命令参数不可实现

*   211    系统状态或系统帮助响应

*   214   帮助信息

*   220     服务就绪

*   221     服务关闭传输信道

*   421     服务未就绪,关闭传输信道(当必须关闭时,此应答可以作为对任何命令的响应)

*   250   要求的邮件操作完成

*   251   用户非本地,将转发向

*   450   要求的邮件操作未完成,邮箱不可用(例如,邮箱忙)

*   550   要求的邮件操作未完成,邮箱不可用(例如,邮箱未找到,或不可访问)

*   451   放弃要求的操作;处理过程中出错

*   551   用户非本地,请尝试

*   452   系统存储不足,要求的操作未执行

*   552   过量的存储分配,要求的操作未执行

*   553   邮箱名不可用,要求的操作未执行(例如邮箱格式错误)

*   354   开始邮件输入,以. 结束

*   554   操作失败

*   535   用户验证失败

*   235   用户验证成功

*   334   等待用户输入验证信息 for next connection>;

3) SMTP 命令应用

我们下需使用telnet 命令实现smtp 邮件的发送,具体操作如下:

220 tdcsw.com ESMTP Sendmail 8.13.8/8.13.8; Wed, 23 Dec 2009 18
:18:18 +0800
HELO tdcsw
250 tdcsw.com Hello x-128-101-1-240.ahc.umn.edu [128.101.1.240], pleased to meet you
MAIL FROM:lily@tdcsw.com
250 2.1.0 lily@tdcsw.com... Sender ok
RCPR TO:sam@163.com
250 2.1.5 carven@tdcsw.pegatroncorp.com... Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
SUBJECT:HELLO
HI:
HAR are you?
.
250 2.0.0 nBNAIIG4000507 Message accepted for delivery
quit
221 2.0.0 tdcsw.maintek.corpnet.asus closing connection
Connection to host lost.

2.     用C++ 实现Mail 发送

为了便于理解, 在此就不封装Mail 类了, 而是以过程式函数方式给出.

1). 首先需要建立TCP 套接字, 连接端口依服务器而定,SMTP 服务默认端口为25, 我们以 默认端口为例

WSADATA wsaData;

int  SockFD;

WSAStartup(MAKEWORD(2,2), &wsaData);

SockFD = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

ServAddr.sin_family = AF_INET;

ServAddr.sin_addr.s_addr = inet_addr (“192.168.1.1”);             //192.168.1.1 为服务器地址

ServAddr.sin_port = htons(25);

connect(SockFD, (struct sockaddr *)&ServAddr, sizeof(ServAddr));

2). 发送SMTP 命令及数据

const char HEADER[] = "HELO smtpSrv/r/n"

"MAIL FROM: sender@126.com/r/n"

"RCPT TO: recv@gmail.com/r/n"

"DATA/r/n"

"FROM: sender@126.com/r/n"

"TO: recv@gmail.com/r/n"

"SUBJECT: this is a test/r/n"

"Date: Fri, 8 Jan 2010 16:12:30/r/n"

"X-Mailer: shadowstar's mailer/r/n"

"MIME-Version: 1.0/r/n"

"Content-type: text/plain/r/n/r/n";

//send HEADER

send(SockFD, HEADER, strlen(HEADER), 0);

const char CONTENT[]="this is content./r/n";

//send CONTENT

send(SockFD, CONTENT, strlen(CONTENT), 0);

send(SockFD, "./r/n", strlen("./r/n"), 0);   //end

send(SockFD, "QUIT/r/n", strlen("QUIT/r/n"), 0); //quit

mail 发送的功能基本上就完成了, 当然, 如果是应用的话还是需要很多改动的地方的, 比如说添加附件等.

3). 附件功能

要使用SMTP 发送附件, 需要对SMTP 头信息进行说明, 改变Content-type 及为每一段正文添加BOUNDARY 名,示例如下:

"DATA/r/n"

"FROM: sender@126.com/r/n"

"TO: recv@gmail.com/r/n"

"SUBJECT: this is a test/r/n"

"Date: Fri, 8 Jan 2010 16:12:30/r/n"

"X-Mailer: shadowstar's mailer/r/n"

"MIME-Version: 1.0/r/n"

"Content-type: multipart/mixed; boundary=/"#BOUNDARY#/"/r/n/r/n";

// 正文

"--#BOUNDARY#/r/n"

"Content-Type: text/plain; charset=gb2312/r/n"

"Content-Transfer-Encoding: quoted-printable/r/n"

邮件正文……….

// 附件

"/r/n--#BOUNDARY#/r/n"

"Content-Type: application/octet-stream; name=att.txt/r/n"

"Content-Disposition: attachment; filename=att.txt/r/n"

"Content-Transfer-Encoding: base64/r/n"

"/r/n"

附件正信息(base64 编码)…..

Base64 编码函数在网络上很容易找到, 这里就不给出源码了, 如需要支持HTML 格式而又不知道如何写这些头信息, 可以用outlook 或foxmail 写一封支持HTML 格式的mail, 查看其原文信息, 依照相同的格式发送就行了.

4). 实现抄送及密送

在SMTP 命令集中并没有RCPT CC 或RCPT BCC 相关命令, 那要如何来实现抄送和密送功能呢?

在网络上找到这样一句话: “ 所有的接收者协商都通过RCPT TO 命令来实现,如果是BCC ,则协商发送后在对方接收时被删掉信封接收者”, 开始一直不明白这句话是什么意思? 后来通看查看foxmail 的邮件原文发现:

Date: Wed, 6 Jan 2010 12:11:48 +0800

From: "carven_li" < carven_li @smtp.com>

To: "carven" <carven@smtp.com>

Cc: "sam" <sam@smtp.com>,

"yoyo" <yoyo@smtp.com>

BCC: "clara" <clara@tsmtp.com>

Subject: t

X-mailer: Foxmail 5.0 [cn]

Mime-Version: 1.0

Content-Type: multipart/mixed;

boundary="=====001_Dragon237244850520_====="

才恍然大悟, 所谓的” 协商” 应该就是指发送方在Data 中指定哪些为CC, 哪些为BCC, 默认情况下什么都不写,只发送第一个RCPT TO 的mail, 其他的都被过滤掉.

SMTP邮件传输协议发送邮件和附件(转)的更多相关文章

  1. SMTP邮件传输协议发送邮件和附件

    在以前接触的项目中,一直都是在做网站时用到了发送mail 的功能,在asp 和.net 中都有相关的发送mail 的类, 实现起来非常简单.最近这段时间因工作需要在C++ 中使用发送mail 的功能, ...

  2. C#System.Net.Mail采用简单邮件传输协议发送邮件

    引用: using System.Net.Mail; public class EmailHelper { public static bool SendEmail(string title, str ...

  3. smtp 邮件传输协议 qq版实现

    qq: telnet smtp.qq.com 587 (qq邮箱说明:http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28& ...

  4. SMTP 简单邮件传输协议

    SMTP 锁定 本词条由“科普中国”百科科学词条编写与应用工作项目 审核 . SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传 ...

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

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

  6. 【RL-TCPnet网络教程】第33章 SMTP简单邮件传输协议基础知识

    第33章      SMTP简单邮件传输协议基础知识 本章节为大家讲解SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)的基础知识,方便后面章节的实战操作. (本 ...

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

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

  8. Laravel自带SMTP邮件组件实现发送邮件(QQ、163、企业邮箱都可)

    Laravel自带SMTP邮件组件实现发送邮件(QQ.163.企业邮箱都可)     laravel自带SMTP邮件配置和遇到的坑 laravel自带SwiftMailer库,集成了多种邮件API,可 ...

  9. JavaMail学习之一-邮件传输协议

    协议:规定好的格式就是协议.就像http协议有请求协议和响应协议,邮件传输也分为发.收邮件的协议. 邮件协议分3种: 发邮件的:SMTP (Simple Mail Transport  Protoca ...

随机推荐

  1. MySQL FEDERATED 存储引擎

    MySQL中针对不同的功能需求提供了不同的存储引擎.所谓的存储引擎也就是MySQL下特定接口的具体实现. FEDERATED是其中一个专门针对远程数据库的实现.一般情况下在本地数据库中建表会在数据库目 ...

  2. JavaScript中的鼠标滚轮事件详解

    JavaScript中的鼠标滚轮事件详解/*Firefox注册事件*/ ~~~Firefox: addEventListener('DOMMouseScroll', handler, false)if ...

  3. Php 使用 fsockopen发送http请求

    <?php function HTTP_Post($URL,$data, $referrer="") { // parsing the given URL $URL_Info ...

  4. HDU1284钱币兑换问题( 母函数打表)

    题意:在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法.请你编程序计算出共有多少种兑法. 原题http://acm.hdu.edu.cn/showproblem.php?pid=128 ...

  5. hdu4370 0 or 1【最短路+建图】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4297627.html   ---by 墨染之樱花 题目链接:http://acm.hdu.ed ...

  6. js如何判断一个对象是不是Array?(转载)

    js如何判断一个对象是不是Array? 在开发中,我们经常需要判断某个对象是否为数组类型,在Js中检测对象类型的常见方法都有哪些呢? typeof 操作符 对于Function, String, Nu ...

  7. 把Web Form项目转换成MVC项目

    http://umbraco.com/follow-us/blog-archive/2013/7/14/moving-from-webforms-to-mvc.aspx https://codinga ...

  8. [译]Stairway to Integration Services Level 11 - 日志配置

    介绍 在前一个章节我们讨论了事先行为,分享了如何操作默认的行为和时间冒泡,并且介绍了父子模型. 本文中,我们会配置SSIS日志. 进行简单及高级日志配置,存储,和检索的实验.并且生成自定义日志信息. ...

  9. 前端CSS规范大全

    一.文件规范 1.文件均归档至约定的目录中(具体要求以豆瓣的CSS规范为例进行讲解): 所有的CSS分为两大类:通用类和业务类.通用的CSS文件,放在如下目录中: 基本样式库 /css/core 通用 ...

  10. LeetCode 二叉树的最小深度

    计算二叉树的最小深度.最小深度定义为从root到叶子节点的最小路径. public class Solution { public int run(TreeNode root) { if(root = ...