电子邮件协议及GO发送QQ邮件

1、电子邮件的工做机制

image-20200531204042406

提供电子邮件服务的协议叫作:SMTP(Simple Mail Transfer Protocol)为了可以高效安全的进行数据的传输,SMTP协议底层使用的TCP实现两端的链接。html

早期的电子邮件收发的工做机制如上图所示。发送端和接收端之间经过SMTP底层的TCP简历链接。经过网络直接将邮件发送到对方的磁盘上。golang

可是问题也随之而来:安全

image-20200531204517018

若是接收方没有开机,或者开机了可是没有链接网络,那么就不能经过SMTP协议创建链接,这时发送端只能是个隔一段时间后重试,直到接收端开机了,联网了,发送端才能成功的将邮件发送给接收方。问题很明显,接收方只要不开机,发送方的邮件就不能发送出去,若是是东方国家和西方国家之间的两我的各自在各自的白天才开机,那岂不是他们之间的邮件根本不可能发送出去了?服务器

为了解决这个问题,邮件服务器出现了:网络

image-20200531205111380

这时收发邮件的工做机制就演变成了上图那样。发送方 面向 邮件服务器发送邮件,而无论接收方是否开机,是否联网,接收方经过上线后使用POP3(Post Office Proto-col)从邮件服务器接收邮件。dom

整个过程当中,邮件服务器是不会断电的。tcp

1.1 SMTP

经过上图能够看到,SMTP是发送电子邮件时使用的协议。 它底层使用tcp的25号端口。在这个tcp链接上进行控制,应答,以及数据的传输。ide

客户端以文本的方式发送请求,邮件服务器每次回复3位数字做为应答。好比客户端首次会发送 HELO<domain>表示请求创建链接。正常的话邮件服务器会回复250,表示完成请求命令。3d

SMTP协议中规定,以'.'最为邮件正文的结束符。当正文前面有一个'.'或者有两个'.' 都要进行特殊处理。code

SMTP不会校验发送者,因此咱们常常会收到垃圾邮件,听说也会有“POP before SMTP” 和“SMTP认证”机制,来防止冒充发送人。从而减小垃圾邮件的数量。

1.2 POP3

POP服务器也是一台一直处于充电状态的服务器。

客户端经过pop3协议从pop服务器上接收发送方发过来的协议,可是在接收以前是须要进行用户身份验证的,也就是说,客户端得将本身的帐号密码发送到POP服务器,经过验证后才能取回属于本身的邮件

POP与SMTP同样,都是基于TCP链接完成相应的操做的。

1.3 IMAP

IMAP和POP协议同样都是接收电子邮件时使用的协议。

若是使用IMAP,即便不用将电子邮件下载到本地也能够阅读。由于IMAP实现了字啊服务端处理MIME类型的数据,因此他能实现当一封电子邮件有10个附件时,它能直接打开其中的某一个。并且在服务端做出已读/未读,等状体的修改。

2、邮件地址

邮件地址一般都是由两部分组成: 名称@地址

常见的像 123@qq.com 这种邮件的地址。

123就是名称,qq.com就是地址。 电子邮件的地址和域名构造相同,后面的com是顶级域名。

如今的电子邮件地址由DNS统一管理。DNS里面存储着各个邮件地址,和这个邮件地址做为发送地址时所对应的邮件服务器的域名信息。咱们把这种映射关系称为MX记录。由于方才说了,对如今的邮件发送机制来讲,发送者是将邮件发送到邮件服务器上。那经过查询DNS中的MX记录,就能知道xxx@qq.com. xxx@163.com 这种不一样的邮件后缀所对应的邮件服务器的域名,经过域名进一步找到这个机器。

3、MIME信息

最初的很长一段时间里,邮件只能发送文本信息。后台能发送的数据类型已经被拓展到了MIME。能够发送诸如gif, video,png,jpg,jpeg,text/plain 等等类型的数据。具体发送啥样的信息,经过Content-Type定义。

4、使用golang发送qq邮件

实例代码以下:

package mail

import (
	"strconv"
)
import "gopkg.in/gomail.v2"

func SendMail(mailTo []string, subject string, body string) error {
  
	mailConn := map[string]string{
		"user": "6464xxxx8@qq.com", // 邮件发送者的地址
		"pass": "trsxxxxxxxxxxcd",  // qq邮箱填受权码,百度一下获取方式。
		"host": "smtp.qq.com", // 发送将邮件发送给腾讯的smtp邮件服务器
		"port": "465",   // 发送邮件使用的端口
	}
	port, _ := strconv.Atoi(mailConn["port"])
  
	m := gomail.NewMessage()
	m.SetHeader("From", m.FormatAddress(mailConn["user"], "自动化成绩查询"))
	m.SetHeader("To", mailTo...)    //发送给多个用户
	m.SetHeader("Subject", subject) //设置邮件主题
	 m.SetBody("text/html", body)    //设置邮件正文
  
	d := gomail.NewDialer(mailConn["host"], port, mailConn["user"], mailConn["pass"])
	err := d.DialAndSend(m)
	return err
}

	/*
	发送邮件
	stuEmail:学生的邮箱
	subject:标题
	body:发送的内容
  */
func DoSendMail(stuEmail , subject, body string) (e error) {
	mailTo := []string{stuEmail}
	err := SendMail(mailTo, subject, body)
	if err != nil {
		e = err
		return e
	}
	return nil
}

//func main() {
//	//定义收件人
//	mailTo := []string{
//		"2693xxxx8@qq.com",
//		"196xxxxx30@qq.com",
//	}
//	//邮件主题为"Hello"
//	subject := "Hi 出成绩了"
//	// 邮件正文
//	body := "请查收您的新成绩"
//
//	err := SendMail(mailTo, subject, body)
//	if err != nil {
//		log.Println(err)
//		fmt.Println("send fail")
//		return
//	}
//	fmt.Println("send successfully")
//}
相关文章
相关标签/搜索