分享
  1. 首页
  2. 文章

Go 语言 SMTP指令发邮件(实例)

juxuny · · 5004 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

简单邮件传输协议(SMTP)是一种基于文本的电子邮件传输协议,是在因特网中用于在邮件服务器之间交换邮件的协议。SMTP是应用层的服务,可以适应于各种网络系统。SMTP的命令和响应都是基于文本,以命令行为单位,换行符为CR/LF(\r\n)。响应信息一般只有一行,由一个3位数的代码开始,后面可附上很简短的文字说明。

SMTP要经过建立连接、传送邮件和释放连接3个阶段。具体为:

(1)建立TCP连接。
(2)客户端向服务器发送HELLO命令以标识发件人自己的身份,然后客户端发送MAIL命令。(EHLO 是扩展指令,不同服务器有不同指令)
(3)服务器端以OK作为响应,表示准备接收。
(4)客户端发送RCPT命令。
(5)服务器端表示是否愿意为收件人接收邮件。
(6)协商结束,发送邮件,用命令DATA发送输入内容。


下面是以smtp.163.com 服务器为例:

package mail
import (
	"encoding/base64"
	"fmt"
	"net"
	"time"
)
const (
	tb string = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
)
type Sender struct {
	UserName string
	Password string
	From string
	To string
	Subject string
	Text string
	Host string
}
func NewSender(host, userName, password string, to string, subject, text string) (r_sender Sender) {
	r_sender.UserName = userName
	r_sender.Password = password
	r_sender.From = userName
	r_sender.To = to
	r_sender.Subject = subject
	r_sender.Text = text
	r_sender.Host = host
	return
}
func (this *Sender) SendMail() (e error) {
	var (
		deadline time.Duration = 5 * time.Second
		encoding *base64.Encoding
		buf []byte = make([]byte, 512)
		r int
	)
	encoding = base64.NewEncoding(tb)
	conn, e := net.Dial("tcp", this.Host)
	if e != nil {
		return
	}
	defer conn.Close()
	conn.SetDeadline(time.Now().Add(deadline))
	r, e = conn.Read(buf)
	if e != nil {
		return
	}
	fmt.Println(string(buf[:r-1]))
	conn.Write([]byte("EHLO Juxuny\r\n"))
	conn.SetDeadline(time.Now().Add(deadline))
	r, e = conn.Read(buf)
	if e != nil {
		return
	}
	fmt.Println(string(buf[:r-1]))
	conn.Write([]byte("AUTH LOGIN\r\n"))
	conn.SetDeadline(time.Now().Add(deadline))
	r, e = conn.Read(buf)
	if e != nil {
		return
	}
	fmt.Println(string(buf[:r-1]))
	conn.Write([]byte(encoding.EncodeToString([]byte(this.UserName)) + "\r\n"))
	conn.SetDeadline(time.Now().Add(deadline))
	r, e = conn.Read(buf)
	if e != nil {
		return
	}
	fmt.Println(string(buf[:r-1]))
	conn.Write([]byte(encoding.EncodeToString([]byte(this.Password)) + "\r\n"))
	conn.SetDeadline(time.Now().Add(deadline))
	r, e = conn.Read(buf)
	if e != nil {
		return
	}
	fmt.Println(string(buf[:r-1]))
	conn.Write([]byte("MAIL FROM: <" + this.From + ">" + "\r\n"))
	conn.SetDeadline(time.Now().Add(deadline))
	r, e = conn.Read(buf)
	if e != nil {
		return
	}
	fmt.Println(string(buf[:r-1]))
	conn.Write([]byte("RCPT TO <" + this.To + ">\r\n"))
	conn.SetDeadline(time.Now().Add(deadline))
	r, e = conn.Read(buf)
	if e != nil {
		return
	}
	fmt.Println(string(buf[:r-1]))
	conn.Write([]byte("DATA\r\n"))
	conn.Write([]byte("\r\n"))
	conn.Write([]byte("Message-ID: <" + this.From + ">\r\n"))
	conn.Write([]byte("X-Mailer: <MMail 1.0>"))
	conn.Write([]byte("MIME-Version: 1.0"))
	conn.Write([]byte("Content-Type: text/plain"))
	conn.Write([]byte("From: <" + this.From + ">\r\n"))
	conn.Write([]byte("To: <" + this.To + ">\r\n"))
	conn.Write([]byte("Subject: " + this.Subject + "\r\n"))
	conn.Write([]byte("\r\n"))
	conn.Write([]byte(this.Text))
	conn.Write([]byte("\r\n.\r\n"))
	time.Sleep(5e9)
	conn.Write([]byte("QUIT\r\n"))
	conn.SetDeadline(time.Now().Add(deadline))
	r, e = conn.Read(buf)
	if e != nil {
		fmt.Println(e)
		return
	}
	fmt.Println(string(buf[:r-1]))
	return
}


package main
import (
	"./mail"
	"fmt"
)
//NewSender(host, userName, password string, to []string, subject, text string)
func main() {
	s := mail.NewSender("smtp.163.com:25",
		"killuaxyz@163.com",
		"**********",
		"976813280@qq.com",
		"hello mail",
		"Test mail")
	e := s.SendMail()
	if e != nil {
		fmt.Println(e)
	}
}

输出结果:
220 163.com Anti-spam GT for Coremail System (163com[20121016])
250-mail
250-PIPELINING
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN PLAIN
250-coremail 1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2Urz5c00UCa0xDrUUUUj
250-STARTTLS
250 8BITMIME
334 dXNlcm5hbWU6
334 UGFzc3dvcmQ6
235 Authentication successful
250 Mail OK
250 Mail OK
354 End data with <CR><LF>.<CR><LF>
250 Mail OK queued as smtp10,DsCowEBJW2Q4BQJTGF3hBA--.94S2 1392641336
421 closing transmission channel

连接成功就返回:
220 163.com Anti-spam GT for Coremail System (163com[20121016])

conn.Write([]byte("AUTHLOGIN\r\n")) 之后,服务器返回:334 dXNlcm5hbWU6

(使用base64Decode ,去解密 "dXNlcm5hbWU6" 其实就是"username:" )

这里就发送经过base64加密的用户名

对应的,收到 334 UGFzc3dvcmQ6 之后,就要发送经过base64加密的帐号密码过去,如果验证成功,服务器返回:235 Authentication successful


有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:juxuny

查看原文:Go 语言 SMTP指令发邮件(实例)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
5004 次点击
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏