面试之SMTP POP3

一.使用域名的别名记录(CNAME),让多域名管理轻松到极点!

简单地说,SMTPPOP3/IMAP

举个例子,你坐在电脑边用mail client写完邮件,点击‘发送’。这时你的mail client会发消息给邮件服务器上的SMTP service。这时有两种情况:

1. 如果邮件的收信人也是处于同一个domain,比如从http://163.com发送给163的邮箱,SMTP service只需要转给localPOP3 Service即可

2. 如果邮件收信人是另外的domain,比如http://163.com发送给http://sina.com SMTP service需要通过询问DNS,找到属于sinaSMTP servicehost

 smtp

https://blog.csdn.net/yun_weiguo/article/details/44649841

https://blog.csdn.net/u014558484/article/details/53130798

  • 3537

事先声明,整个过程以LOGIN认证方式为例,其他认证方式大同小异。按照时间顺序,主要分为22个步骤。

1、客户端TCP连接服务器25端口;

2、三次握手以后,连接建立成功,服务器主动推送服务就绪信息

网易邮箱一般都形如“220 163.com Anti-spam GT for Coremail System (163com[20111010])”;雅虎邮箱形如“220 smtp108.mail.gq1.yahoo.com ESMTP”;Google邮箱形如“220 mx.google.com ESMTP nw8sm917193igc.7”。其中220代表服务就绪,每一条服务就绪信息以“\r\n”为结尾标示符。    

3、客户端向服务器说明身份

交代自己认证SMTP服务器的域名,例如雅虎邮箱的SMTP服务器为smtp.mail.yahoo.com,则发送“EHLO smtp.mail.yahoo.com\r\n”。

4、如果身份有效,则服务器进入等待认证状态,主动推送自身支持的所有SMTP认证方式

网易邮箱发送的内容如下:

  1. 250-mail\r\n  
  2. 250-PIPELINING\r\n  
  3. 250-AUTH LOGIN PLAIN\r\n  
  4. 250-AUTH=LOGIN PLAIN\r\n  
  5. 250-coremail\r\n 1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UFWNUp_UCa0xDrUUUUj  
  6. 250-STARTTLS\r\n  
  7. 250 8BITMIME\r\n  

表示其支持LOGIN、PLAIN两种认证方式;

雅虎邮箱发送的内容如下:

  1. 250-smtp206.mail.ne1.yahoo.com\r\n  
  2. 250-AUTH LOGIN PLAIN XYMCOOKIE\r\n  
  3. 250-PIPELINING\r\n  
  4. 250 8BITMIME\r\n  

表示其支持LOGIN、PLAIN、XYMCOOKIE三种认证方式。

5、客户端判断自身是否支持服务器提供的SMTP认证方式

如果认证方式指定“auto”则采用服务端提供的第一个认证方式,如果指定其他方式,则判断服务端是否支持该方式,否则返回错误。
这一歩相当关键,因为客户端程序可以根据具体的认证方式加载相应插件来完成认证过程。

6、客户端向服务器请求认证

发送“AUTH LOGIN\r\n”。

7、如果认证请求合理,服务器将进入等待用户输入状态

发送“334 VXNlcm5hbWU6\r\n”,334表示等待客户端输入,VXNlcm5hbWU6表示等待输入用户名。

8、客户端向服务器发送转码后的用户名

发送经过Base64转码后的用户名(taotown)”dGFvdG93bg==\r\n“。

9、服务器再次进入等待用户输入状态

发送“334 UGFzc3dvcmQ6\r\n”,334表示等待客户端输入,UGFzc3dvcmQ6表示等待输入密码

10、客户端向服务器发送转码后的密码

发送经过Base64转码后的密码(Haier)“SGFpZXI=\r\n”。

11、如果用户名或者密码出错,服务器将返回530错误,发送“530 Access denied\r\n”,表示认证失败。否则将返回235,发送“235 OK, go ahead\r\n”,表示用户认证成功。

12、客户端告诉服务器邮件来自何方

发送“MAIL FROM: <taotown@yahoo.com> \r\n”。

13、如果合理,服务端返回250表示成功

发送“250 OK , completed\r\n”。

14、客户端告诉服务器邮件去往何地

发送“RCPT TO: <taotown@126.com> \r\n”。

15、如果合理,服务器返回250表示成功

发送“250 OK , completed\r\n”。

16、客户端告诉服务器自己准备发送邮件正文

发送“DATA\r\n”。

17、服务器返回354,表示自己已经作好接受邮件的准备

发送“354 Start Mail. End with CRLF.CRLF\r\n”,提醒客户端开始发送邮件并以“.”结束。

18、客户端发送邮件正文(如果正文过长,可以分多次发送)

发送

  1. “To: taotown@126.com\r\n  
  2. Subject: Hello Trevor\r\n  
  3. My name is TaoZhen\r\n  
  4. ”。  

19、客户端发送完正文以后,紧接着发送结束符

发送“.”。

20、如果合理,服务端返回250表示成功

发送“250 OK , completed\r\n”。

21、邮件发送结束,客户端请求断开连接

发送“QUIT\r\n”。

22、服务器返回211,提示断开申请被采纳,并主动断开连接,整个邮件发送过程结束。

发送“221 Service Closing transmission\r\n”。

附:如果服务端传过来的错误码后面紧跟这”-“,则说明该次消息分了很多节,直到最后一节没有”-“为止。


资料二

在以前接触的项目中,一直都是在做网站时用到了发送mail 的功能,在asp 和.net 中都有相关的发送mail 的类, 实现起来非常简单。最近这段时间因工作需要在C++ 中使用发送mail 的功能,上网搜了一大堆资料,终于得以实现,总结自己开发过程中碰到的一些问题,希望对需的人有所帮助, 由于能力有限, 文中不免有些误解之处,望大家能指正!!

其实,使用C++ 发送mail 也是很简的事, 只需要了解一点SMTP 协议和socket 编程就OK 了, 网络上也有很多高人写好的mail 类源码,有兴趣的朋友可以下载看看.

 

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.

 


   一封邮件的发送和接收过程:

     

     SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)定义了邮件客户端与SMTP服务器之间,以及两台SMTP服务器之间发送邮件的通信规则 。SMTP协议属于TCP/IP协议族,通信双方采用一问一答的命令/响应形式进行对话,且定了对话的规则和所有命令/响应的语法格式。 

 用户代理

用户代理UA(User Agent)是用户与电子邮件系 统的交互接口,一般来说它就是我们PC机上的一个程序。Windows上常见的用户代理是Foxmail和Outlook Express。

用户代理提供一个好的用户界面,它提取用户在其界面填写的各项信息,生成一封符合SMTP等邮件标准的邮件,然后采用SMTP协议将邮件发送到发送端邮件服务器。

     邮件服务器

邮件服务器是电子邮件系统的核心,它用来发送和接收邮件。邮件服务器不同于普通PC的是它几乎是全天工作的,所以它可以在任何时候为用户提供服务,很多ISP都提供免费的邮件服务器,如126提供smtp.126.com邮件服务器。邮件服务器向其它邮件服务器转发邮件也是采用SMTP协议。

    

一般情况下,一封邮件的发送和接收过程如下。

1) 发信人在用户代理里编辑邮件,包括填写发信人邮箱、收信人邮箱和邮件标题等等。

2) 用户代理提取发信人编辑的信息,生成一封符合邮件格式标准(RFC822)的邮件。

3) 用户代理用SMTP将邮件发送到发送端邮件服务器(即发信人邮箱所对应的邮件服务器)。

4) 发送端邮件服务器用SMTP将邮件发送到接收端邮件服务器(即收信人邮箱所对应的邮件服务器)。

5) 收信人调用用户代理。用户代理用POP3协议从接收端邮件服务器取回邮件。

6) 用户代理解析收到的邮件,以适当的形式呈现在收信人面前。


一个具体的SMTP通信(如发送端邮件服务器与接收端服务器的通信)的过程如下。

1) 发送端邮件服务器(以下简称客户端)与接收端邮件服务器(以下简称服务器)的25号端口建立TCP连 接。

2) 客户端向服务器发送各种命令,来请求各种服务(如认证、指定发送人和接收人)。

3) 服务器解析用户的命令,做出相应动作并返回给客户端一个响应。

4) 2)和3)交替进行,直到所有邮件都发送完或两者的 连接被意外中断。


SMTP命令格式说明
ehlo<SP><domain><CRLF>       ehlo命令是SMTP邮件发送程序与SMTP邮件接收程序建立连接后必须发送的第一条SMTP命令,参数<domain>表示SMTP邮件发送者的主机名。
ehlo命令用于替代传统SMTP协议中的helo命令。
auth<SP><para><CRLF>      如果SMTP邮件接收程序需要SMTP邮件发送程序进行认证时,它会向SMTP邮件发送程序提示它所采用的认证方式,SMTP邮件发送程序接着应该使用这个命令回应SMTP邮件接收程序,参数<para>表示回应的认证方式,通常是SMTP邮件接收程序先前提示的认证方式。
mail<SP>From:<reverse-path><CRLF>    此命令用于指定邮件发送者的邮箱地址,参数<reverse-path>表示发件人的邮箱地址
rcpt<SP>To:<forword-path><CRLF>     此命令用于指定邮件接收者的邮箱地址,参数<forward-path>表示接收者的邮箱地址。如果邮件要发送给多个接收者,那么应使用多条rcpt<SP>To命令来分别指定每一个接收者的邮箱地址。
data<CRLF>     此命令用于表示SMTP邮件发送程序准备开始输入邮件内容,在这个命令后面发送的所有数据都将被当做邮件内容,直至遇到“<CRLF>.<CRLF>"标志符,则表示邮件内容结束。
quit<CRLF>    此命令表示要结束邮件发送过程,SMTP邮件接收程序接收到此命令后,将关闭与SMTP邮件发送程序的网络连接。

常用的响应如下所示:

220<domain>服务就绪

250要求的邮件操作完成

235 用户验证成功

334 等待用户输入验证信息

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

221<domain>服务关闭

响应状态码的最高位数字代表了不同的分类,当其为 2 时表示命令执行成功;为5时表示命令执行失败;为3时表示命令没有完成。




注意:

    使用"auth login"命令登录到Smtp服务器,登录使用的用户名和密码必须经过Base64加密。

    邮件头使用下面的三个字段来指明

    1. from字段用于指明邮件的发送人
    2. to字段用于指明邮件的收件人
    3. subject字段用于指明邮件的主题
     

  • 3537

事先声明,整个过程以LOGIN认证方式为例,其他认证方式大同小异。按照时间顺序,主要分为22个步骤。

1、客户端TCP连接服务器25端口;

2、三次握手以后,连接建立成功,服务器主动推送服务就绪信息

网易邮箱一般都形如“220 163.com Anti-spam GT for Coremail System (163com[20111010])”;雅虎邮箱形如“220 smtp108.mail.gq1.yahoo.com ESMTP”;Google邮箱形如“220 mx.google.com ESMTP nw8sm917193igc.7”。其中220代表服务就绪,每一条服务就绪信息以“\r\n”为结尾标示符。    

3、客户端向服务器说明身份

交代自己认证SMTP服务器的域名,例如雅虎邮箱的SMTP服务器为smtp.mail.yahoo.com,则发送“EHLO smtp.mail.yahoo.com\r\n”。

4、如果身份有效,则服务器进入等待认证状态,主动推送自身支持的所有SMTP认证方式

网易邮箱发送的内容如下:

  1. 250-mail\r\n  
  2. 250-PIPELINING\r\n  
  3. 250-AUTH LOGIN PLAIN\r\n  
  4. 250-AUTH=LOGIN PLAIN\r\n  
  5. 250-coremail\r\n 1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UFWNUp_UCa0xDrUUUUj  
  6. 250-STARTTLS\r\n  
  7. 250 8BITMIME\r\n  

表示其支持LOGIN、PLAIN两种认证方式;

雅虎邮箱发送的内容如下:

  1. 250-smtp206.mail.ne1.yahoo.com\r\n  
  2. 250-AUTH LOGIN PLAIN XYMCOOKIE\r\n  
  3. 250-PIPELINING\r\n  
  4. 250 8BITMIME\r\n  

表示其支持LOGIN、PLAIN、XYMCOOKIE三种认证方式。

5、客户端判断自身是否支持服务器提供的SMTP认证方式

如果认证方式指定“auto”则采用服务端提供的第一个认证方式,如果指定其他方式,则判断服务端是否支持该方式,否则返回错误。
这一歩相当关键,因为客户端程序可以根据具体的认证方式加载相应插件来完成认证过程。

6、客户端向服务器请求认证

发送“AUTH LOGIN\r\n”。

7、如果认证请求合理,服务器将进入等待用户输入状态

发送“334 VXNlcm5hbWU6\r\n”,334表示等待客户端输入,VXNlcm5hbWU6表示等待输入用户名。

8、客户端向服务器发送转码后的用户名

发送经过Base64转码后的用户名(taotown)”dGFvdG93bg==\r\n“。

9、服务器再次进入等待用户输入状态

发送“334 UGFzc3dvcmQ6\r\n”,334表示等待客户端输入,UGFzc3dvcmQ6表示等待输入密码

10、客户端向服务器发送转码后的密码

发送经过Base64转码后的密码(Haier)“SGFpZXI=\r\n”。

11、如果用户名或者密码出错,服务器将返回530错误,发送“530 Access denied\r\n”,表示认证失败。否则将返回235,发送“235 OK, go ahead\r\n”,表示用户认证成功。

12、客户端告诉服务器邮件来自何方

发送“MAIL FROM: <taotown@yahoo.com> \r\n”。

13、如果合理,服务端返回250表示成功

发送“250 OK , completed\r\n”。

14、客户端告诉服务器邮件去往何地

发送“RCPT TO: <taotown@126.com> \r\n”。

15、如果合理,服务器返回250表示成功

发送“250 OK , completed\r\n”。

16、客户端告诉服务器自己准备发送邮件正文

发送“DATA\r\n”。

17、服务器返回354,表示自己已经作好接受邮件的准备

发送“354 Start Mail. End with CRLF.CRLF\r\n”,提醒客户端开始发送邮件并以“.”结束。

18、客户端发送邮件正文(如果正文过长,可以分多次发送)

发送

  1. “To: taotown@126.com\r\n  
  2. Subject: Hello Trevor\r\n  
  3. My name is TaoZhen\r\n  
  4. ”。  

19、客户端发送完正文以后,紧接着发送结束符

发送“.”。

20、如果合理,服务端返回250表示成功

发送“250 OK , completed\r\n”。

21、邮件发送结束,客户端请求断开连接

发送“QUIT\r\n”。

22、服务器返回211,提示断开申请被采纳,并主动断开连接,整个邮件发送过程结束。

发送“221 Service Closing transmission\r\n”。

附:如果服务端传过来的错误码后面紧跟这”-“,则说明该次消息分了很多节,直到最后一节没有”-“为止。


资料二

在以前接触的项目中,一直都是在做网站时用到了发送mail 的功能,在asp 和.net 中都有相关的发送mail 的类, 实现起来非常简单。最近这段时间因工作需要在C++ 中使用发送mail 的功能,上网搜了一大堆资料,终于得以实现,总结自己开发过程中碰到的一些问题,希望对需的人有所帮助, 由于能力有限, 文中不免有些误解之处,望大家能指正!!

其实,使用C++ 发送mail 也是很简的事, 只需要了解一点SMTP 协议和socket 编程就OK 了, 网络上也有很多高人写好的mail 类源码,有兴趣的朋友可以下载看看.

 

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.

 


POP3

https://blog.csdn.net/u014558484/article/details/53150038

  • 3537

事先声明,整个过程以LOGIN认证方式为例,其他认证方式大同小异。按照时间顺序,主要分为22个步骤。

1、客户端TCP连接服务器25端口;

2、三次握手以后,连接建立成功,服务器主动推送服务就绪信息

网易邮箱一般都形如“220 163.com Anti-spam GT for Coremail System (163com[20111010])”;雅虎邮箱形如“220 smtp108.mail.gq1.yahoo.com ESMTP”;Google邮箱形如“220 mx.google.com ESMTP nw8sm917193igc.7”。其中220代表服务就绪,每一条服务就绪信息以“\r\n”为结尾标示符。    

3、客户端向服务器说明身份

交代自己认证SMTP服务器的域名,例如雅虎邮箱的SMTP服务器为smtp.mail.yahoo.com,则发送“EHLO smtp.mail.yahoo.com\r\n”。

4、如果身份有效,则服务器进入等待认证状态,主动推送自身支持的所有SMTP认证方式

网易邮箱发送的内容如下:

  1. 250-mail\r\n  
  2. 250-PIPELINING\r\n  
  3. 250-AUTH LOGIN PLAIN\r\n  
  4. 250-AUTH=LOGIN PLAIN\r\n  
  5. 250-coremail\r\n 1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UFWNUp_UCa0xDrUUUUj  
  6. 250-STARTTLS\r\n  
  7. 250 8BITMIME\r\n  

表示其支持LOGIN、PLAIN两种认证方式;

雅虎邮箱发送的内容如下:

  1. 250-smtp206.mail.ne1.yahoo.com\r\n  
  2. 250-AUTH LOGIN PLAIN XYMCOOKIE\r\n  
  3. 250-PIPELINING\r\n  
  4. 250 8BITMIME\r\n  

表示其支持LOGIN、PLAIN、XYMCOOKIE三种认证方式。

5、客户端判断自身是否支持服务器提供的SMTP认证方式

如果认证方式指定“auto”则采用服务端提供的第一个认证方式,如果指定其他方式,则判断服务端是否支持该方式,否则返回错误。
这一歩相当关键,因为客户端程序可以根据具体的认证方式加载相应插件来完成认证过程。

6、客户端向服务器请求认证

发送“AUTH LOGIN\r\n”。

7、如果认证请求合理,服务器将进入等待用户输入状态

发送“334 VXNlcm5hbWU6\r\n”,334表示等待客户端输入,VXNlcm5hbWU6表示等待输入用户名。

8、客户端向服务器发送转码后的用户名

发送经过Base64转码后的用户名(taotown)”dGFvdG93bg==\r\n“。

9、服务器再次进入等待用户输入状态

发送“334 UGFzc3dvcmQ6\r\n”,334表示等待客户端输入,UGFzc3dvcmQ6表示等待输入密码

10、客户端向服务器发送转码后的密码

发送经过Base64转码后的密码(Haier)“SGFpZXI=\r\n”。

11、如果用户名或者密码出错,服务器将返回530错误,发送“530 Access denied\r\n”,表示认证失败。否则将返回235,发送“235 OK, go ahead\r\n”,表示用户认证成功。

12、客户端告诉服务器邮件来自何方

发送“MAIL FROM: <taotown@yahoo.com> \r\n”。

13、如果合理,服务端返回250表示成功

发送“250 OK , completed\r\n”。

14、客户端告诉服务器邮件去往何地

发送“RCPT TO: <taotown@126.com> \r\n”。

15、如果合理,服务器返回250表示成功

发送“250 OK , completed\r\n”。

16、客户端告诉服务器自己准备发送邮件正文

发送“DATA\r\n”。

17、服务器返回354,表示自己已经作好接受邮件的准备

发送“354 Start Mail. End with CRLF.CRLF\r\n”,提醒客户端开始发送邮件并以“.”结束。

18、客户端发送邮件正文(如果正文过长,可以分多次发送)

发送

  1. “To: taotown@126.com\r\n  
  2. Subject: Hello Trevor\r\n  
  3. My name is TaoZhen\r\n  
  4. ”。  

19、客户端发送完正文以后,紧接着发送结束符

发送“.”。

20、如果合理,服务端返回250表示成功

发送“250 OK , completed\r\n”。

21、邮件发送结束,客户端请求断开连接

发送“QUIT\r\n”。

22、服务器返回211,提示断开申请被采纳,并主动断开连接,整个邮件发送过程结束。

发送“221 Service Closing transmission\r\n”。

附:如果服务端传过来的错误码后面紧跟这”-“,则说明该次消息分了很多节,直到最后一节没有”-“为止。


资料二

在以前接触的项目中,一直都是在做网站时用到了发送mail 的功能,在asp 和.net 中都有相关的发送mail 的类, 实现起来非常简单。最近这段时间因工作需要在C++ 中使用发送mail 的功能,上网搜了一大堆资料,终于得以实现,总结自己开发过程中碰到的一些问题,希望对需的人有所帮助, 由于能力有限, 文中不免有些误解之处,望大家能指正!!

其实,使用C++ 发送mail 也是很简的事, 只需要了解一点SMTP 协议和socket 编程就OK 了, 网络上也有很多高人写好的mail 类源码,有兴趣的朋友可以下载看看.

 

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.

 


POP3全称为Post Office Protocol version3,即邮局协议第3版。它被用户代理用来邮件服务器取得邮件。POP3采用的也是C/S通信 模型


   用户从邮件服务器上接收邮件的典型通信过程如下。

1) 用户运行用户代理(如Foxmail, Outlook Express)。

2) 用户代理(以下简称客户端)与邮件服务器(以下简称服务器端)的110端口建立TCP连 接。

3) 客户端向服务器端发出各种命令,来请求各种服务(如查询邮箱信息,下载某封邮件等)。

4) 服务端解析用户的命令,做出相应动作并返回给客户端一个响应。

5) 3)和4)交替进行,直到接收完所有邮件转到步骤6),或两者的连接被意外中断而直接退出。

6) 用户代理解析从服务器端获得的邮件,以适当地形式(如可读)的形式呈现给用户。

  <SP>代表空格,<CRLF>代表回车和换行。

   

POP3命令格式说明
user<SP>username<CRLF>      user 命令是POP3客户端程序与POP3邮件服务器建立连接后通常发送的第一条命令,参数 username 表示收件人的帐户名称。
pass<SP>password<CRLF>      pass 命令是在user命令成功通过后,POP3客户端程序接着发送的命令,它用于传递帐户的密码,参数 password 表示帐户的密码。
apop<SP>name,digest<CRLF>      apop 命令用于替代user和pass命令,它以MD5 数字摘要的形式向POP3邮件服务器提交帐户密码。
stat<CRLF>     stat 命令用于查询邮箱中的统计信息,例如:邮箱中的邮件数量和邮件占用的字节大小等。
uidl<SP>msg#<CRLF>     uidl 命令用于查询某封邮件的唯一标志符,参数msg#表示邮件的序号,是一个从1开始编号的数字。
list<SP>[MSG#]<CRLF>     list 命令用于列出邮箱中的邮件信息,参数 msg#是一个可选参数,表示邮件的序号。当不指定参数时,POP3服务器列出邮箱中所有的邮件信息;当指定参数msg#时,POP3服务器只返回序号对应的邮件信息。
retr<SP>msg#<CRLF>    retr 命令用于获取某封邮件的内容,参数 msg#表示邮件的序号。
dele<SP>msg#<CRLF>    dele 命令用于在某封邮件上设置删除标记,参数msg#表示邮件的序号。POP3服务器执行dele命令时,只是为邮件设置了删除标记,并没有真正把邮件删除掉,只有POP3客户端发出quit命令后,POP3服务器才会真正删除所有设置了删除标记的邮件。
rest<CRLF>    rest 命令用于清除所有邮件的删除标记。
top<SP>msg#<SP>n<CRLF>    top 命令用于获取某封邮件的邮件头和邮件体中的前n行内容,参数msg#表示邮件的序号,参数n表示要返回邮件的前几行内容。使用这条命令以提高 Web Mail系统(通过Web站点上收发邮件)中的邮件列表显示的处理效率,因为这种情况下不需要获取每封邮件的完整内容,而是仅仅需要获取每封邮件的邮件头信息。
noop<CRLF>    noop 命令用于检测POP3客户端与POP3服务器的连接情况。
quit<CRLF>    quit 命令表示要结束邮件接收过程,POP3服务器接收到此命令后,将删除所有设置了删除标记的邮件,并关闭与POP3客户端程序的网络连接。

        对于POP3客户程序发送的每一条POP3命令,POP3服务器都将回应一些响应信息。响应信息由一行或多行文本信息组成,其中的第一行始终以“+OK” 或 “-ERR” 开头,它们分别表示当前命令执行成功或执行失败。


POP3协议中有三种状态,认正状态,处理状态,和更新状态。命令的执行可以改变协议的状态,而对于具体的某命令,它只能在具体的某状态下使用


客户机与服务器刚与服务器建立连接时,它的状态为认证状态;一旦客户机提供了自己身份并被成功地确认,即由认可状态转入处理状态; 在完成相应的操作后客户机发出QUIT命令(具体说明见后续内容),则进入更新状态,更新之后又重返认可状态;当然在认可状态下执行QUIT命令,可释放连接。

---建立连接---|认可|--认证成 功--|处理|--执行QUIT--|更新| 
|_______ -QUIT结束_________________|


IMAP协议在 RFC2060文档中定义,目前使用的是第4个版本,所以也称为IMAP4。IMAP协议相对于POP3协议而言,它定了更为强大的邮件接收功能,主要体现在以下一些方面:
  1. IMAP具有摘要浏览功能,可以让用户在读完所有邮件的主题、发件人、大小等信息后,再由用户做出是否下载或直接在服务器上删除的决定。
  2. IMAP可以让用户有选择性地下载邮件附件。例如一封邮件包含3个附件,如果用户确定其中只有2个附件对自已有用,就可只下载这2个附件,而不必下载整封邮件,从而节省了下载时间。
  3. IMAP可以让用户在邮件服务器上创建自己的邮件夹,分类保存各个邮件。

早期人们在使用电子邮件时,都是使用普通文本内容的电子邮件内容进行交流,由于互联网的迅猛发展,人们已不满足电子邮件仅仅是用来交换文本信息,而希望使用电子邮件来交换更为丰富多彩的多媒体信息,例如,在邮件中嵌入图片、声音、动画和附件等二进制数据。但在以往的邮件发送协议RFC822文档中定义,只能发送文本信息,无法发送非文本的邮件,针对这个问题,人们后来专门为此定义了MIME(Multipurpose Internet Mail Extension,多用途Internet邮件扩展)协议。

    MIME协议用于定义复杂的邮件体格式,它可以表达多段平行的文本内容和非文本的邮件内容,例如,在邮件体中内嵌的图像数据和邮件附件等。另外,MIME协议的数据格式也可以避免邮件内容在传输过程发生信息丢失。对于表示某个具体资源的MIME消息,它的消息头中需要指定资源的数据类型;对于MIME组合消息,它的消息中需要指定组合关系。具体资源的数据类型和组合消息的组合关系,都是通过消息头中的Content-Type头字段来指定的。Content-Type字段中的内容以“主类型/子类型”的形式出现,主类型有text、image、audio、video、application、multipart、message等,分别表示文本、图片、音频、视频、应用程序、组合结构、消息等。每个主类型下面都有多个子类型,例如text类型包含plain、html、xml、css等子类型。multipart主类型用于表示MIME组合消息,它是MIME协议中最重要的一种类型。一封MIME邮件中的MIME消息可以有三种组合关系:混合、关联、选择,它们对应MIME类型如下:

 

  • multipart/mixed
表示消息体中的内容是混和组合类型,内容可以是文本、声音和附件等不同邮件内容的混和体。比如一封邮件中即包含附件,邮件内容还引用内嵌的图片或附件资源,这种类型邮件的MIME类型就必须定义为multipart/mixed。
  • multipart/related
表示消息体中的内容是关联(依赖)组合类型。比如:邮件内容有一个img标签,这个标签的src属性指向的是邮件内部的一个图片资源,所以这封邮件MIME类型就应该定义为multipart/related
  • multipart/alternative
表示消息体中的内容是选择组合类型,例如一封邮件的邮件正文同时采用HTML格式和普通文本格式进行表达时,就可以将它们嵌套在一个multipart/alterntive类型的组合消息中。这种做法的好处在于如果邮件阅读程序不支持HTML格式时,可以采用其中的文本格式进行替代。
    一封最复杂的电子邮件的基本情况为:含有邮件正文和邮件附件,邮件正文可以同时使用HTML格式和普通文本格式表示,并且HTML格式的正文中又引用了其它的内嵌资源。对于这种最复杂的电子邮件,可以采用下图所示的MIME消息结构进行描述:
    从上图中可以看出,如果在邮件中要添加附件,就必须将整封邮件的MIME类型定义为multipart/mixed;如果要在HTML格式的正文中引用内嵌资源,那就要定义multipart/related类型的MIME消息;如果普通文本内容与HTML文本内容共存,那就要定义multipart/alternative类型的MIME消息。
    注意:如果整封邮件中只有普通文本内容与HTML文本内容,那么整封邮件的MIME类型则应定义为multipart/alternative;如果整封邮件中包含有HTML文本内容和内嵌资源,但不包含附件,那么整封邮件的MIME类型则应该定义为multipart/related。


    参考:
     http://www.cnblogs.com/diegodu/p/4097202.html


  • 3537

事先声明,整个过程以LOGIN认证方式为例,其他认证方式大同小异。按照时间顺序,主要分为22个步骤。

1、客户端TCP连接服务器25端口;

2、三次握手以后,连接建立成功,服务器主动推送服务就绪信息

网易邮箱一般都形如“220 163.com Anti-spam GT for Coremail System (163com[20111010])”;雅虎邮箱形如“220 smtp108.mail.gq1.yahoo.com ESMTP”;Google邮箱形如“220 mx.google.com ESMTP nw8sm917193igc.7”。其中220代表服务就绪,每一条服务就绪信息以“\r\n”为结尾标示符。    

3、客户端向服务器说明身份

交代自己认证SMTP服务器的域名,例如雅虎邮箱的SMTP服务器为smtp.mail.yahoo.com,则发送“EHLO smtp.mail.yahoo.com\r\n”。

4、如果身份有效,则服务器进入等待认证状态,主动推送自身支持的所有SMTP认证方式

网易邮箱发送的内容如下:

  1. 250-mail\r\n  
  2. 250-PIPELINING\r\n  
  3. 250-AUTH LOGIN PLAIN\r\n  
  4. 250-AUTH=LOGIN PLAIN\r\n  
  5. 250-coremail\r\n 1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UFWNUp_UCa0xDrUUUUj  
  6. 250-STARTTLS\r\n  
  7. 250 8BITMIME\r\n  

表示其支持LOGIN、PLAIN两种认证方式;

雅虎邮箱发送的内容如下:

  1. 250-smtp206.mail.ne1.yahoo.com\r\n  
  2. 250-AUTH LOGIN PLAIN XYMCOOKIE\r\n  
  3. 250-PIPELINING\r\n  
  4. 250 8BITMIME\r\n  

表示其支持LOGIN、PLAIN、XYMCOOKIE三种认证方式。

5、客户端判断自身是否支持服务器提供的SMTP认证方式

如果认证方式指定“auto”则采用服务端提供的第一个认证方式,如果指定其他方式,则判断服务端是否支持该方式,否则返回错误。
这一歩相当关键,因为客户端程序可以根据具体的认证方式加载相应插件来完成认证过程。

6、客户端向服务器请求认证

发送“AUTH LOGIN\r\n”。

7、如果认证请求合理,服务器将进入等待用户输入状态

发送“334 VXNlcm5hbWU6\r\n”,334表示等待客户端输入,VXNlcm5hbWU6表示等待输入用户名。

8、客户端向服务器发送转码后的用户名

发送经过Base64转码后的用户名(taotown)”dGFvdG93bg==\r\n“。

9、服务器再次进入等待用户输入状态

发送“334 UGFzc3dvcmQ6\r\n”,334表示等待客户端输入,UGFzc3dvcmQ6表示等待输入密码

10、客户端向服务器发送转码后的密码

发送经过Base64转码后的密码(Haier)“SGFpZXI=\r\n”。

11、如果用户名或者密码出错,服务器将返回530错误,发送“530 Access denied\r\n”,表示认证失败。否则将返回235,发送“235 OK, go ahead\r\n”,表示用户认证成功。

12、客户端告诉服务器邮件来自何方

发送“MAIL FROM: <taotown@yahoo.com> \r\n”。

13、如果合理,服务端返回250表示成功

发送“250 OK , completed\r\n”。

14、客户端告诉服务器邮件去往何地

发送“RCPT TO: <taotown@126.com> \r\n”。

15、如果合理,服务器返回250表示成功

发送“250 OK , completed\r\n”。

16、客户端告诉服务器自己准备发送邮件正文

发送“DATA\r\n”。

17、服务器返回354,表示自己已经作好接受邮件的准备

发送“354 Start Mail. End with CRLF.CRLF\r\n”,提醒客户端开始发送邮件并以“.”结束。

18、客户端发送邮件正文(如果正文过长,可以分多次发送)

发送

  1. “To: taotown@126.com\r\n  
  2. Subject: Hello Trevor\r\n  
  3. My name is TaoZhen\r\n  
  4. ”。  

19、客户端发送完正文以后,紧接着发送结束符

发送“.”。

20、如果合理,服务端返回250表示成功

发送“250 OK , completed\r\n”。

21、邮件发送结束,客户端请求断开连接

发送“QUIT\r\n”。

22、服务器返回211,提示断开申请被采纳,并主动断开连接,整个邮件发送过程结束。

发送“221 Service Closing transmission\r\n”。

附:如果服务端传过来的错误码后面紧跟这”-“,则说明该次消息分了很多节,直到最后一节没有”-“为止。


资料二

在以前接触的项目中,一直都是在做网站时用到了发送mail 的功能,在asp 和.net 中都有相关的发送mail 的类, 实现起来非常简单。最近这段时间因工作需要在C++ 中使用发送mail 的功能,上网搜了一大堆资料,终于得以实现,总结自己开发过程中碰到的一些问题,希望对需的人有所帮助, 由于能力有限, 文中不免有些误解之处,望大家能指正!!

其实,使用C++ 发送mail 也是很简的事, 只需要了解一点SMTP 协议和socket 编程就OK 了, 网络上也有很多高人写好的mail 类源码,有兴趣的朋友可以下载看看.

 

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.

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值