VCSMTP协议电子邮件传送剖析

上传人:平*** 文档编号:9860645 上传时间:2017-10-04 格式:DOC 页数:6 大小:50.63KB
返回 下载 相关 举报
VCSMTP协议电子邮件传送剖析_第1页
第1页 / 共6页
VCSMTP协议电子邮件传送剖析_第2页
第2页 / 共6页
VCSMTP协议电子邮件传送剖析_第3页
第3页 / 共6页
VCSMTP协议电子邮件传送剖析_第4页
第4页 / 共6页
VCSMTP协议电子邮件传送剖析_第5页
第5页 / 共6页
点击查看更多>>
资源描述

《VCSMTP协议电子邮件传送剖析》由会员分享,可在线阅读,更多相关《VCSMTP协议电子邮件传送剖析(6页珍藏版)》请在金锄头文库上搜索。

1、VC+ SMTP 协议电子邮件传送剖析2002-11-19 信息产业部电子第二十二研究所青岛分所朗锐yesky摘要:本文介绍了一种采用 SMTP 协议规范并通过直接使用 SMTP 协议命令而在程序中实现电子邮件传送的方法。并在 VC+开发环境下给出了部分关键的实现代码。前言电子邮件服务作为 Internet 上应用最多和最广的服务项目得到了非常广泛的应用,在网络应用中也起到非常重要的作用。如同其他的网络服务,电子邮件系统也有其使用的传输协议,包括 SMTP(Simple Mail Transfer Protocol,简单邮件传输协议) 、POP(Post Office Protocol,邮局协

2、议)和 IMAP(Internet Message Access Protocal,消息访问协议)等,这些协议应用于电子邮件的发送和接收。一些邮件处理软件如 OutLook Express 和 FoxMail 等就是按照 SMTP 和 POP3 协议结合 Windows Sockets 套接字进行设计来收发邮件的。本文以SMTP 协议为研究对象,在 Visual C+ 6.0 编程环境下按照 SMTP 协议通过套接字发送SMTP 命令,接收并处理邮件服务器的反馈信息,从而实现对电子邮件的发送。SMTP 协议的通讯模型和会话流程SMTP 协议通讯模型SMTP 协议是 TCP/IP 协议族中的一员

3、,主要对如何将电子邮件从发送方地址传送到接收方地址,也即是对传输的规则做了规定。SMTP 协议的通信模型并不复杂,主要工作集中在发送 SMTP 和接收 SMTP 上:首先针对用户发出的邮件请求,由发送 SMTP 建立一条连接到接收 SMTP 的双工通讯链路,这里的接收 SMTP 是相对于发送 SMTP 而言的,实际上它既可以是最终的接收者也可以是中间传送者。发送 SMTP 负责向接收 SMTP 发送 SMTP 命令,而接收 SMTP 则负责接收并反馈应答。可大致用下面的通讯模型示意图来表示:SMTP 协议的命令和应答从前面的通讯模型可以看出 SMTP 协议在发送 SMTP 和接收 SMTP 之

4、间的会话是靠发送SMTP 的 SMTP 命令和接收 SMTP 反馈的应答来完成的。在通讯链路建立后,发送 SMTP 发送 MAIL 命令指令邮件发送者,若接收 SMTP 此时可以接收邮件则作出 OK 的应答,然后发送SMTP 继续发出 RCPT 命令以确认邮件是否收到,如果接收到就作出 OK 的应答,否则就发出拒绝接收应答,但这并不会对整个邮件操作造成影响。双方如此反复多次,直至邮件处理完毕。SMTP 协议共包含 10 个 SMTP 命令,列表如下:SMTP 命令 命令说明HELLO domain CRLF 识别发送方到接收 SMTP 的一个 HELLO 命令MAIL FROM:reverse

5、-pathCRLF reverse-path为发送者地址。此命令告诉接收方一个新邮件发送的开始,并对所有的状态和缓冲区进行初始化。此命令开始一个邮件传输处理,最终完成将邮件数据传送到一个或多个邮箱中。RCPT TO:forward-path CRLF forward-path标识各个邮件接收者的地址DATA CRLF 接收 SMTP 将把其后的行为看作邮件数据去处理,以CRLF.CRLF标识数据的结尾。REST CRLF 退出/复位当前的邮件传输NOOP CRLF 要求接收 SMTP 仅做 OK 应答。 (用于测试)QUIT CRLF 要求接收 SMTP 返回一个 OK 应答并关闭传输。VRF

6、Y string CRLF 验证指定的邮箱是否存在,由于安全因素,服务器多禁止此命令。EXPN string CRLF 验证给定的邮箱列表是否存在,扩充邮箱列表,也常禁止使用。HELP CRLF 查询服务器支持什么命令注:CRLF为回车、换行,ASCII 码分别为 13、10(十进制) 。SMTP 协议的每一个命令都会返回一个应答码,应答码的每一个数字都是有特定含义的,如第一位数字为 2 时表示命令成功;为 5 表失败;3 表没有完成。一些较复杂的邮件程序利用该特点,首先检查应答码的首数字,并根据其值来决定下一步的动作。下面将 SMTP 的应答码列表如下:应答码 说明501 参数格式错误502

7、 命令不可实现503 错误的命令序列504 命令参数不可实现211 系统状态或系统帮助响应214 帮助信息220 domain服务就绪221 domain服务关闭421 domain服务未就绪,关闭传输信道250 要求的邮件操作完成251 用户非本地,将转发向forward-path450 要求的邮件操作未完成,邮箱不可用550 要求的邮件操作未完成,邮箱不可用451 放弃要求的操作;处理过程中出错551 用户非本地,请尝试forward-path 452 系统存储不足,要求的操作未执行552 过量的存储分配,要求的操作未执行553 邮箱名不可用,要求的操作未执行354 开始邮件输入,以.结束

8、554 操作失败在应用程序中使用 SMTP 协议SMTP 协议的会话流程在进行程序设计之前有必要弄清 SMTP 协议的会话流程,其实前面介绍的内容已经可以大致勾勒出用 SMTP 发送邮件的框架了,对于一次普通的邮件发送,其过程大致为:先建立 TCP 连接,随后客户端发出 HELLO 命令以标识发件人自己的身份,并继续由客户端发送 MAIL 命令,如服务器应答为 OK,可继续发送 RCPT 命令来标识电子邮件的收件人,在这里可以有多个 RCPT 行,而服务器端则表示是否愿意为收件人接受该邮件。在双方协商结束后,用命令 DATA 将邮件发送出去,其中对表示结束的. 也一并发送出去。随后结束本次发送

9、过程,以 QUIT 命令退出。下面通过一个实例,从 发送邮件到 来更详细直观地描述此会话流程:R:220 Simple Mail Transfer Service ReadyS:HELLO R:250 S:MAIL FROM:R:250 OKS:RCPT TO:R:250 OKS:DATAR:354 Start mail input;end with CRLF.CRLFS:R:250 OKS:QUITR:221 Service closing transmission channel邮件的格式化由于电子邮件结构上的特殊性,在传输时是不能当作简单的文本来直接处理的,而必须按照一定的格式对

10、邮件头和邮件体进行格式化处理之后才可以被发送。需要进行格式化的部分主要有:发件人地址、收件人地址、主题和发送日期等。在 RFC 文档的 RFC 822 里对邮件的格式化有详尽的说明,有关详情请参阅该文档。下面通过VC+6.0 按照 RFC 822 文档规定将格式化邮件的部分编写如下(部分代码):/邮件头准备strTemp = _T( From: ) + m_strFrom; file:/发件人地址add_header_line( (LPCTSTR)strTemp );strTemp = _T( To: ) + m_strTo; file:/收件人地址add_header_line( (LPCT

11、STR)strTemp );m_tDateTime = m_tDateTime.GetCurrentTime();/发送时间strTemp = _T( Data: );strTemp += m_tDateTime.Format( %a, %d %b %y %H:%M:%S %Z );add_header_line( (LPCTSTR)strTemp );strTemp = _T( Subject: ) + m_strSubject; file:/主题add_header_line( (LPCTSTR)strTemp );file:/邮件头结束m_strHeader += _T( rn );fi

12、le:/邮件体准备if( m_strBody.Right( 2 ) != _T( rn ) ) file:/确认最后以回车换行结束m_strBody += _T( rn ); 其中 add_header_line(LPCTSTR szHeaderLine)函数用于把 szHeaderLine 指向的字串追加到 m_strHeader 后面。其中,格式化后的邮件头保存在 m_strHeader 里,格式化后的邮件体保存在 m_strBody 中。由 Socket 套接字为 SMTP 提供网络通讯基础许多网络程序都是采用 Socket 套接字实现的,对于一些标准的网络协议如HTTP、FTP 和 S

13、MTP 等协议的编程也是基于套接字程序的,只是端口号不再是随意设定而要由协议来指定,比如 HTTP 端口在 80、FTP 是 21,而 SMTP 则是25。Socket 只是提供在指定的端口上同指定的服务器从事网络上的通讯能力,至于客户和服务器之间是如何通讯的则由网络协议来规定,这对于套接字是完全透明的。因此可以使用 Socket 套接字为程序提供网络通讯的能力,而对于网络通讯连路建立好之后采取什么样的通讯应答则要按 SMTP 协议的规定去执行了。Socket 套接字网络编程方面的文章资料非常丰富,限于本文篇幅,在此不再赘述,有关详情请参阅相关文档。为简便起见,没有采用编写较复杂的 Windo

14、ws Sockets API 进行编程,而是使用经过较好封装的 MFC 的 CSocket 类。在正式使用套接字之前,也要先用 AfxSocketInit()函数对套接字进行初始化,然后用 Create()创建套接字对象,并由该套接字通过Connect()建立同邮件服务器的连接。如果一切正常,再后续的工作中就是遵循SMTP 协议的约定来使用 Send() 、Receive()函数来发送 SMTP 命令和接收邮件服务器发来的应答码以完成对邮件的传送。SMTP 会话应答的实现在同邮件服务器建立好链路连接后就可以按前面介绍过的会话流程进行程序设计了,对于 SMTP 命令的发送,可按命令格式将其组帧完

15、毕后用 CSocket 类的 Send()函数将其发送到服务器,并通过 CSocket 类的 Receive()函数接收从邮件服务器发来的应答码,并根据 SMTP 协议的应答码表对其做出响应的处理。下面是用于接收应答码的函数 get_response()的部分实现代码:BOOL CSMTP:get_response( UINT response_expected )/输入参数为希望的应答码/ m_wsSMTPServer 为 CSocket 的类对象,调用 Receive()将应答码接收到缓存/ response_buf 中m_wsSMTPServer.Receive( response_buf, RESPONSE_BUFFER_SIZE )sResponse = response_buf;sscanf( (LPCTSTR)sResponse.Left( 3 ), _T( %d ), &response );pResp = &response_table response_expected ;file:/检验收到的应答码是否是所希望得到的if( response != pResp-nResponse )/不相等的话进行错误处理return FALSE;return TRUE;

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 中学教育 > 试题/考题

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号