SMTP邮件传输协议发送邮件和附件(转)
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邮件传输协议发送邮件和附件(转)的更多相关文章
- SMTP邮件传输协议发送邮件和附件
在以前接触的项目中,一直都是在做网站时用到了发送mail 的功能,在asp 和.net 中都有相关的发送mail 的类, 实现起来非常简单.最近这段时间因工作需要在C++ 中使用发送mail 的功能, ...
- C#System.Net.Mail采用简单邮件传输协议发送邮件
引用: using System.Net.Mail; public class EmailHelper { public static bool SendEmail(string title, str ...
- smtp 邮件传输协议 qq版实现
qq: telnet smtp.qq.com 587 (qq邮箱说明:http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28& ...
- SMTP 简单邮件传输协议
SMTP 锁定 本词条由“科普中国”百科科学词条编写与应用工作项目 审核 . SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传 ...
- 理解邮件传输协议(SMTP、POP3、IMAP、MIME)
http://blog.csdn.net/xyang81/article/details/7672745 电子邮件需要在邮件客户端和邮件服务器之间,以及两个邮件服务器之间进行传递,就必须遵循一定的规则 ...
- 【RL-TCPnet网络教程】第33章 SMTP简单邮件传输协议基础知识
第33章 SMTP简单邮件传输协议基础知识 本章节为大家讲解SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)的基础知识,方便后面章节的实战操作. (本 ...
- 45.简单邮件传输协议 SMTP
一丶简单邮件传输协议 简单邮件传输协议 简单邮件传输协议 SMTP smtplib 模块:(在 Python3版本中,可以通过 SMTP协议发送邮件的模块常为 smtplib, 并且这个模块属于内置模 ...
- Laravel自带SMTP邮件组件实现发送邮件(QQ、163、企业邮箱都可)
Laravel自带SMTP邮件组件实现发送邮件(QQ.163.企业邮箱都可) laravel自带SMTP邮件配置和遇到的坑 laravel自带SwiftMailer库,集成了多种邮件API,可 ...
- JavaMail学习之一-邮件传输协议
协议:规定好的格式就是协议.就像http协议有请求协议和响应协议,邮件传输也分为发.收邮件的协议. 邮件协议分3种: 发邮件的:SMTP (Simple Mail Transport Protoca ...
随机推荐
- 字符串匹配算法1-KMP
前面介绍过,字符串搜索一般来说有三种方式,前缀搜索,后缀搜索,子串搜索.KMP使用的是前缀搜索. 假设p的偏移是i,也就是窗口的位置是i,匹配到位置j+1时发现了不匹配.现在的问题是向前移动窗口到什么 ...
- ajax Session失效如何跳转到登录页面
在Struts应用中,我们发出的请求都会经过 相应的拦截器进行相关处理,一般都会有一个用户登录拦截(Session失效拦截):一般请求的话,如果Session失效时,我们会跳到登录页面,可是如果我们采 ...
- jquery简单的插件
$(function() { $.fn.插件名称 = function(options) { var defaults = { Event : "click", //触发响应事件 ...
- 捕捉小括号获取的内容保存在RegExp的$1 $2..属性中
~~~~捕捉小括号获取的内容保存在RegExp的$1 $2..属性中 var reg=/^(-?\d+)(px|pt|em|in)?$/;if(reg.test(svalue)){ ...
- 算法导论 6.5.9 堆实现K路归并问题
问题: 设计一个时间复杂度为O(NlogK)的算法,它能够将K个有序链表合并为一个有序链表,这里的N为所有输入链表包含的总的元素个数 分析: 该问题为经典的利用堆完成K路归并的问题: 当K个序列满足一 ...
- http://download.qt-project.org/archive/qt/4.5/qt-all-opensource-src-4.5.2.tar.bz2
Index of /archive/qt/4.5 http://download.qt-project.org/archive/qt/4.5/qt-all-opensource-src-4.5.2.t ...
- mysqlcluster笔记
1.config的datamemory和indexmemory规定的内存占有量会在ndb启动时直接占用掉,所以在计算内存时,这两个加起来要小于ndb的内存,这两个还只是数据和索引的内存,查询或者插入时 ...
- 使用Groovy进行依赖注入
为什么选择Groovy? 传统的依赖注入是XML,对我而言,可读性太差,太不美观,强烈地想换一个方式进行依赖注入,Groovy作为XML的替代方案,在Spring4之后被引入,是基于JVM的一门方言, ...
- 问题解决: WordPress on SAE注册邮件无法发送
方法一: 修改代码 Step 1: 改写wp-includes/pluggable.php, 把WordPress默认邮件设置改为SMTP模式. // Set to use PHP's mail() ...
- poj2774之最长公共子串
Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 18794 Accepted: 77 ...