三、C#下创建基于TcpClient发送邮件组件
在上一节在Dos命令行下测试SMTP处事器连接时,已经使用了SMTP的部分命令,但是其时无法对信息进行编码和解码,也就无法继续进行身份验证和信息传输。在.Net库中,我们可以使用System.Net.Sockets.TcpClient类实现上一节发送邮件组件的同样成果(其实OpenSmtp也同样是基于这个组件开发的),这里仅作为测试以丰裕了解SMTP协议规范。
1、SMTP命令及其响应
邮件发送的根基过程是一问一答的方法与处事器交流的,所以我们需要先了解关于SMTP命令及其响应,详情请查阅RFC821。
常用的SMTP/ESMTP命令(命令的执行有必然挨次)包孕:
命令 感化HELO 使用标准的SMTP,向处事器标识用户身份
EHLO 使用ESMTP,向处事器标识用户身份,针对撑持ESMTP的处事器
STARTTLS 启用TLS,将普通连接提升为安适连接,针对撑持STARTTLS 的处事器
AUTH LOGIN 开始认证措施
MAIL FROM 指定发件人地点
RCPT TO 指定单个邮件接收人;可以有多个RCPT TO
DATA 传输数据,处事器接收到<CRLF>.<CRLF>就遏制接收数据
VRFY 验证指定的用户/邮箱是否存在,常被禁用
EXPN 验证指定的邮箱列表是否存在,常被禁用
HELP 盘问处事器撑持的命令
NOOP 无操纵,处事器响应 250 OK
RSET 重置会话,打消当前传输,处事器响应 250 OK
QUIT 结束会话
常见SMTP处事器响应:
500 语法错误,未知命令
501 参数语法错误
502 命令未执行
503 命令挨次错误
504 参数未赋值
211 系统状态,或者系统辅佐响应
214 辅佐信息
220 <domain> 处事就绪
221 <domain> 处事正在*传输通道
421 <domain> 处事不成用,正在*传输通道
250 操纵完成
251 非本地用户;将转发至 <forward-path>
450 操纵未完成:邮箱不成用[例如:邮箱忙]
550 操纵未完成:邮箱不成用[例如:邮箱不存在,不成访谒]
451 操纵打消:措置惩罚惩罚过程中堕落
551 非本地用户;请测验考试 <forward-path>
452 操纵未完成:系统存储空间不敷
552 操纵打消:赶过分配的存储空间
553 操纵未完成:邮箱名不成用[例如:邮箱名语法错误]
354 开始邮件数据输入,以 <CRLF>.<CRLF> 结束
554 操纵掉败
所以如果我们在控制台输出邮件发送全过程应该梗概如下(差别处事器反馈的信息差别,且如果发送带多媒体邮件布局更为庞大),此中Receive是处事器接收数据,Send是向处事器发送数据:
Send: EHLO g1 Receive: 250-mail 250-PIPELINING 250-AUTH LOGIN PLAIN 250-AUTH=LOGIN PLAIN 250-STARTTLS 250 8BITMIME Send: AUTH LOGIN Receive: 334 dXNlcm5hbWU6 Send: cWluZ3NwYWNl Receive: 334 UGFzc3dvcmQ6 Send: NINULFzLnhtdQ== Receive: 235 Authentication successful Send: MAIL FROM: ******@***.com Receive: 250 Mail OK Send: RCPT TO: <******@***.com> Receive: 250 Mail OK Send: DATA Receive: 354 End data with <CR><LF>.<CR><LF> Send: From: <<******@***.com> Send: To: <<******@***.com> Send: Subject: =?utf-8?B?5Y+R6YCBIG0yIHZpYSBoMiBVc2VUY3BDbGllbnQg?= Send: Date: Fri, 16 May 2014 01:17:40 GMT Send: MIME-Version: 1.0 Send: Content-Type: text/html; Send: charset="utf-8" Send: Content-Transfer-Encoding: base64 Send: Send: 5rWL6K+V44CCSnVzdCBhIHRlc3QuPGJyLz48aW1nIHNyYz0nY2lkOlVtVnpiM1Z5WTJVdWFu Send: Qm4nIGFsdD0nJy8+ Send: . Receive: 250 Mail OK queued as AgAi0gCXn8M0Z3VTmF4QAA--.4500S2 Send: QUIT Receive: 221 Bye
2、C#编码实现邮件发送
接下来我们基于.Net类库中TcpClient类实现与处事器的交互:
先成立同样担任于ISendMail接口的类UseTcpClient
同时设定一个内部类Message作为数据载体,界说utf-8作为全局的字符编码,界说base64为全局的传输编码。