go smtp示例
<p><span data-cke-copybin-start="1"><span data-cke-copybin-start="1"></span></span>书接上文<span class="cke_widget_wrapper cke_widget_inline cke_widget_csdnlink cke_widget_wrapper_link-info cke_widget_selected" data-cke-display-name="a" data-cke-filter="off" data-cke-widget-id="0" data-cke-widget-wrapper="1">邮件实现详解,这里我们及我们简单复习一下smtp的指令如下:</span></p><div class="cnblogs_code">
<pre>telnet smtp.<span style="color: rgba(128, 0, 128, 1)">163</span>.com <span style="color: rgba(128, 0, 128, 1)">25</span><span style="color: rgba(0, 0, 0, 1)">
ehlo dz45693
auth login
输入用户名base64
输入密码base64
mail </span><span style="color: rgba(0, 0, 255, 1)">from</span>:<dz45693@<span style="color: rgba(128, 0, 128, 1)">163</span>.com><span style="color: rgba(0, 0, 0, 1)">
rcpt to:</span><dz45693@sina.com><span style="color: rgba(0, 0, 0, 1)">
data
</span><span style="color: rgba(0, 0, 255, 1)">from</span>:<dz45693@<span style="color: rgba(128, 0, 128, 1)">163</span>.com><span style="color: rgba(0, 0, 0, 1)">
to:</span><dz45693@sina.com><span style="color: rgba(0, 0, 0, 1)">
subject:hello world
This </span><span style="color: rgba(0, 0, 255, 1)">is</span> the first email sent by hand <span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> the SMTP protocol
.
quit </span></pre>
</div>
<p><span data-cke-copybin-start="1"><span data-cke-copybin-end="1"><img src="https://img2022.cnblogs.com/blog/209993/202203/209993-20220313182841054-2068185709.png"></span></span></p>
<p>好,那我们下现在用go实现代码让如下: 这里只是一个demo,主要熟悉smtp命令</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">package main
import (
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">bufio</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">encoding/base64</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">fmt</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">net</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">strconv</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">strings</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
)
func main() {
testSmtp()
}
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)"> gConn net.Conn
</span><span style="color: rgba(0, 0, 255, 1)">var</span> gRead *<span style="color: rgba(0, 0, 0, 1)">bufio.Reader
</span><span style="color: rgba(0, 0, 255, 1)">var</span> gWrite *<span style="color: rgba(0, 0, 0, 1)">bufio.Writer
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">可以放到这样的类里</span>
type TcpClient <span style="color: rgba(0, 0, 255, 1)">struct</span><span style="color: rgba(0, 0, 0, 1)"> {
Connnet.Conn
Read</span>*<span style="color: rgba(0, 0, 0, 1)">bufio.Reader
Write </span>*<span style="color: rgba(0, 0, 0, 1)">bufio.Writer
} </span><span style="color: rgba(0, 128, 0, 1)">//
</span><span style="color: rgba(0, 0, 0, 1)">
func Connect(host </span><span style="color: rgba(0, 0, 255, 1)">string</span>, port <span style="color: rgba(0, 0, 255, 1)">int</span>) (net.Conn, *bufio.Reader, *<span style="color: rgba(0, 0, 0, 1)">bufio.Writer) {
addr :</span>= host + <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">:</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> strconv.Itoa(port)
conn, err :</span>= net.Dial(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tcp</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, addr)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> nil, nil, nil
}
reader :</span>=<span style="color: rgba(0, 0, 0, 1)"> bufio.NewReader(conn)
writer :</span>=<span style="color: rgba(0, 0, 0, 1)"> bufio.NewWriter(conn)
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> conn, reader, writer
} </span><span style="color: rgba(0, 128, 0, 1)">//</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">收取一行,可再优化</span>
func RecvLine() <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> {
line, err :</span>= gRead.ReadString(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">\n</span><span style="color: rgba(128, 0, 0, 1)">'</span>) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">如何设定超时?</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
fmt.Print(err)
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 0, 1)">""</span><span style="color: rgba(0, 0, 0, 1)">
}
line </span>= strings.Split(line, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\r</span><span style="color: rgba(128, 0, 0, 1)">"</span>)[<span style="color: rgba(128, 0, 128, 1)">0</span>] <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">还要再去掉 "\r",其实不去掉也可以</span>
<span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> line
}
func SendLine(line </span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">) {
gWrite.WriteString(line </span>+ <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\r\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
gWrite.Flush()
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">解码一行命令,这里比较简单就是按空格进行分隔就行了</span>
func DecodeCmd(line <span style="color: rgba(0, 0, 255, 1)">string</span>, sp <span style="color: rgba(0, 0, 255, 1)">string</span>) []<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> {
tmp :</span>=<span style="color: rgba(0, 0, 0, 1)"> strings.Split(line, sp)
</span><span style="color: rgba(0, 0, 255, 1)">var</span> cmds = []<span style="color: rgba(0, 0, 255, 1)">string</span>{<span style="color: rgba(128, 0, 0, 1)">""</span>, <span style="color: rgba(128, 0, 0, 1)">""</span>, <span style="color: rgba(128, 0, 0, 1)">""</span>, <span style="color: rgba(128, 0, 0, 1)">""</span>, <span style="color: rgba(128, 0, 0, 1)">""</span>} <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">先定义多几个,以面后面使用时产生异常</span>
<span style="color: rgba(0, 0, 255, 1)">for</span> i := <span style="color: rgba(128, 0, 128, 1)">0</span>; i < len(tmp); i++<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> i >=<span style="color: rgba(0, 0, 0, 1)"> len(cmds) {
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">
}
cmds </span>=<span style="color: rgba(0, 0, 0, 1)"> tmp
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> cmds
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">读取多行结果</span>
func RecvMCmd() <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> {
i :</span>= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">
rs :</span>= <span style="color: rgba(128, 0, 0, 1)">""</span><span style="color: rgba(0, 0, 0, 1)">
mLine :</span>= <span style="color: rgba(128, 0, 0, 1)">""</span>
<span style="color: rgba(0, 0, 255, 1)">for</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < <span style="color: rgba(128, 0, 128, 1)">50</span>; i++<span style="color: rgba(0, 0, 0, 1)"> {
rs </span>= RecvLine() <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">只收取一行</span>
mLine = mLine + rs + <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\r\n</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> len(rs) < <span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">
} </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">长度要足够</span>
c4 := rs[<span style="color: rgba(128, 0, 128, 1)">4</span>-<span style="color: rgba(128, 0, 128, 1)">1</span>] <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">第4个字符</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 0, 1)">'</span> <span style="color: rgba(128, 0, 0, 1)">'</span> ==<span style="color: rgba(0, 0, 0, 1)"> c4 {
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">
} </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">第4个字符是空格就表示读取完了</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">也可以判断 "250[空格]"</span>
<span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> mLine
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">简单的测试一下 smtp</span>
<span style="color: rgba(0, 0, 0, 1)">func testSmtp() {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">连接</span>
gConn, gRead, gWrite = Connect(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">smtp.163.com</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 128, 1)">25</span><span style="color: rgba(0, 0, 0, 1)">)
defer gConn.Close()
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">收取一行</span>
line :=<span style="color: rgba(0, 0, 0, 1)"> RecvLine()
fmt.Println(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">recv:</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> line)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">解码一下,这样后面的 EHLO 才能有正确的第二个参数</span>
cmds := DecodeCmd(line, <span style="color: rgba(128, 0, 0, 1)">"</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
domain :</span>= cmds[<span style="color: rgba(128, 0, 128, 1)">1</span>] <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">要从对方的应答中取出域名</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">空格分开的各个命令参数中的第二个
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">发送一个命令</span>
SendLine(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">EHLO</span><span style="color: rgba(128, 0, 0, 1)">"</span> + <span style="color: rgba(128, 0, 0, 1)">"</span> <span style="color: rgba(128, 0, 0, 1)">"</span> + domain) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">domain 要求其实来自 HELO 命令</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">HELO <SP> <domain> <CRLF>
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">收取多行</span>
line =<span style="color: rgba(0, 0, 0, 1)"> RecvMCmd()
fmt.Println(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">recv:</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> line)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">--------------------------------------------------
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">用 base64 登录</span>
SendLine(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">AUTH LOGIN</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">收取一行</span>
line =<span style="color: rgba(0, 0, 0, 1)"> RecvLine()
fmt.Println(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">recv:</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> line)
s :</span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">dz45693</span><span style="color: rgba(128, 0, 0, 1)">"</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">要换成你的用户名,注意 163 邮箱的话不要带后面的 @域名 部分</span>
s = base64.StdEncoding.EncodeToString([]<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">(s))
SendLine(s)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">收取一行</span>
line =<span style="color: rgba(0, 0, 0, 1)"> RecvLine()
fmt.Println(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">recv:</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> line)
s </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">xxxxx</span><span style="color: rgba(128, 0, 0, 1)">"</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">要换成您的密码</span>
s = base64.StdEncoding.EncodeToString([]<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">(s))
SendLine(s)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">收取一行</span>
line =<span style="color: rgba(0, 0, 0, 1)"> RecvLine()
fmt.Println(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">recv:</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> line)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">--------------------------------------------------
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">邮件内容</span>
<span style="color: rgba(0, 0, 255, 1)">from</span> := <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">dz45693@163.com</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
to :</span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">dz45693@sina.com</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
SendLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">MAIL FROM: <</span><span style="color: rgba(128, 0, 0, 1)">"</span> + <span style="color: rgba(0, 0, 255, 1)">from</span> + <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">></span><span style="color: rgba(128, 0, 0, 1)">"</span>) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">注意"<" 符号和前面的空格。空格在协议中有和没有都可能,最好还是有
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">收取一行</span>
line =<span style="color: rgba(0, 0, 0, 1)"> RecvLine()
fmt.Println(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">recv:</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> line)
SendLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">RCPT TO: <</span><span style="color: rgba(128, 0, 0, 1)">"</span> + to + <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">></span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">收取一行</span>
line =<span style="color: rgba(0, 0, 0, 1)"> RecvLine()
fmt.Println(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">recv:</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> line)
SendLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">DATA</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">收取一行</span>
line =<span style="color: rgba(0, 0, 0, 1)"> RecvLine()
fmt.Println(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">recv:</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> line)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">发送邮件头</span>
SendLine(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">from:<dz45693@163.com></span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
SendLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">to:<dz45693@sina.com></span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
SendLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">subject:hello world</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
SendLine(</span><span style="color: rgba(128, 0, 0, 1)">""</span>) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">发送空行 后面就是邮件体</span>
SendLine(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">This is the first email sent by hand using the SMTP protocol</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
SendLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">.</span><span style="color: rgba(128, 0, 0, 1)">"</span>) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">邮件结束符
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">收取一行</span>
line =<span style="color: rgba(0, 0, 0, 1)"> RecvLine()
fmt.Println(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">recv:</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> line)
SendLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">quit</span><span style="color: rgba(128, 0, 0, 1)">"</span>) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">链接推出</span>
line =<span style="color: rgba(0, 0, 0, 1)"> RecvLine()
fmt.Println(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">recv:</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> line)
} </span><span style="color: rgba(0, 128, 0, 1)">//</span></pre>
</div>
<p>运行结果图下:</p>
<p><img src="https://img2022.cnblogs.com/blog/209993/202203/209993-20220313183143346-1687104986.png"></p>
<p> 在go的sdk中提供了SendMail方法【<strong>发送邮件后这个方法会关闭链接</strong>】,实现如下:</p>
<p><img src="https://img2022.cnblogs.com/blog/209993/202203/209993-20220313183749101-1222709924.png"></p>
<p>实现如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">func SendMailBySmtp(){
auth :</span>= smtp.PlainAuth(<span style="color: rgba(128, 0, 0, 1)">""</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">dz45693@163.com</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">xxx</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">smtp.163.com</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
to :</span>= []<span style="color: rgba(0, 0, 255, 1)">string</span>{<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">dz45693@sina.com</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">}
image,_:</span>=ioutil.ReadFile(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">d:\\Downloads\\1.png</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
imageBase64:</span>=<span style="color: rgba(0, 0, 0, 1)">base64.StdEncoding.EncodeToString(image)
msg :</span>= []<span style="color: rgba(0, 0, 255, 1)">byte</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">from:dz45693@163.com\r\n</span><span style="color: rgba(128, 0, 0, 1)">"</span>+
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">to: dz45693@sina.com\r\n</span><span style="color: rgba(128, 0, 0, 1)">"</span> +
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Subject: hello,subject!\r\n</span><span style="color: rgba(128, 0, 0, 1)">"</span>+
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Content-Type:multipart/mixed;boundary=a\r\n</span><span style="color: rgba(128, 0, 0, 1)">"</span>+
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Mime-Version:1.0\r\n</span><span style="color: rgba(128, 0, 0, 1)">"</span>+
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\r\n</span><span style="color: rgba(128, 0, 0, 1)">"</span> +
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">--a\r\n</span><span style="color: rgba(128, 0, 0, 1)">"</span>+
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Content-type:text/plain;charset=utf-8\r\n</span><span style="color: rgba(128, 0, 0, 1)">"</span>+
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Content-Transfer-Encoding:quoted-printable\r\n</span><span style="color: rgba(128, 0, 0, 1)">"</span>+
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\r\n</span><span style="color: rgba(128, 0, 0, 1)">"</span>+
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">此处为正文内容!\r\n</span><span style="color: rgba(128, 0, 0, 1)">"</span>+
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">--a\r\n</span><span style="color: rgba(128, 0, 0, 1)">"</span>+
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Content-type:image/jpg;name=1.jpg\r\n</span><span style="color: rgba(128, 0, 0, 1)">"</span>+
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Content-Transfer-Encoding:base64\r\n</span><span style="color: rgba(128, 0, 0, 1)">"</span>+
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\r\n</span><span style="color: rgba(128, 0, 0, 1)">"</span>+<span style="color: rgba(0, 0, 0, 1)">
imageBase64</span>+<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\r\n</span><span style="color: rgba(128, 0, 0, 1)">"</span>+
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">--a--\r\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
err :</span>= smtp.SendMail(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">smtp.163.com:25</span><span style="color: rgba(128, 0, 0, 1)">"</span>, auth, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">dz45693@163.com</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, to, msg)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
fmt.Println(err)
}
}</span></pre>
</div>
<p>运行效果</p>
<p><img src="https://img2022.cnblogs.com/blog/209993/202203/209993-20220313184550091-406229720.png"></p>
<p> </p>
<p> 示例如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">func SendMailByGomailOne(){
m :</span>=<span style="color: rgba(0, 0, 0, 1)"> gomail.NewMessage()
m.SetAddressHeader(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">From</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">dz45693@163.com</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">dz45693</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
m.SetHeader(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">To</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">dz45693@sina.com</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
m.SetHeader(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Subject</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">hello SendMailByGomailOne!</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
m.Embed(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">d:\\Downloads\\1.png</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
m.SetBody(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">text/html</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">此处为正文121333!</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
d :</span>= gomail.NewDialer(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">smtp.163.com</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 128, 1)">25</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">dz45693@163.com</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">xxxx#</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err := d.DialAndSend(m); err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
panic(err)
}
}</span></pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2022.cnblogs.com/blog/209993/202203/209993-20220313185335209-1879091795.png"></p>
<p>来我们看看DialAndSend的实现如下: </p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">package gomail
import (
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">crypto/tls</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">fmt</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">io</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">net</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">net/smtp</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">strings</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">time</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> A Dialer is a dialer to an SMTP server.</span>
type Dialer <span style="color: rgba(0, 0, 255, 1)">struct</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Host represents the host of the SMTP server.</span>
Host <span style="color: rgba(0, 0, 255, 1)">string</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Port represents the port of the SMTP server.</span>
Port <span style="color: rgba(0, 0, 255, 1)">int</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Username is the username to use to authenticate to the SMTP server.</span>
Username <span style="color: rgba(0, 0, 255, 1)">string</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Password is the password to use to authenticate to the SMTP server.</span>
Password <span style="color: rgba(0, 0, 255, 1)">string</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Auth represents the authentication mechanism used to authenticate to the
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> SMTP server.</span>
<span style="color: rgba(0, 0, 0, 1)"> Auth smtp.Auth
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> SSL defines whether an SSL connection is used. It should be false in
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> most cases since the authentication mechanism should use the STARTTLS
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> extension instead.</span>
SSL <span style="color: rgba(0, 0, 255, 1)">bool</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> TSLConfig represents the TLS configuration used for the TLS (when the
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> STARTTLS extension is used) or SSL connection.</span>
TLSConfig *<span style="color: rgba(0, 0, 0, 1)">tls.Config
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> LocalName is the hostname sent to the SMTP server with the HELO command.
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> By default, "localhost" is sent.</span>
LocalName <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> NewDialer returns a new SMTP Dialer. The given parameters are used to connect
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> to the SMTP server.</span>
func NewDialer(host <span style="color: rgba(0, 0, 255, 1)">string</span>, port <span style="color: rgba(0, 0, 255, 1)">int</span>, username, password <span style="color: rgba(0, 0, 255, 1)">string</span>) *<span style="color: rgba(0, 0, 0, 1)">Dialer {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> &<span style="color: rgba(0, 0, 0, 1)">Dialer{
Host: host,
Port: port,
Username: username,
Password: password,
SSL: port </span>== <span style="color: rgba(128, 0, 128, 1)">465</span><span style="color: rgba(0, 0, 0, 1)">,
}
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> NewPlainDialer returns a new SMTP Dialer. The given parameters are used to
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> connect to the SMTP server.
</span><span style="color: rgba(0, 128, 0, 1)">//</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Deprecated: Use NewDialer instead.</span>
func NewPlainDialer(host <span style="color: rgba(0, 0, 255, 1)">string</span>, port <span style="color: rgba(0, 0, 255, 1)">int</span>, username, password <span style="color: rgba(0, 0, 255, 1)">string</span>) *<span style="color: rgba(0, 0, 0, 1)">Dialer {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> NewDialer(host, port, username, password)
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Dial dials and authenticates to an SMTP server. The returned SendCloser
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> should be closed when done using it.</span>
func (d *<span style="color: rgba(0, 0, 0, 1)">Dialer) Dial() (SendCloser, error) {
conn, err :</span>= netDialTimeout(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tcp</span><span style="color: rgba(128, 0, 0, 1)">"</span>, addr(d.Host, d.Port), <span style="color: rgba(128, 0, 128, 1)">10</span>*<span style="color: rgba(0, 0, 0, 1)">time.Second)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> nil, err
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> d.SSL {
conn </span>=<span style="color: rgba(0, 0, 0, 1)"> tlsClient(conn, d.tlsConfig())
}
c, err :</span>=<span style="color: rgba(0, 0, 0, 1)"> smtpNewClient(conn, d.Host)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> nil, err
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> d.LocalName != <span style="color: rgba(128, 0, 0, 1)">""</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err := c.Hello(d.LocalName); err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> nil, err
}
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> !<span style="color: rgba(0, 0, 0, 1)">d.SSL {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> ok, _ := c.Extension(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">STARTTLS</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">); ok {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err := c.StartTLS(d.tlsConfig()); err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
c.Close()
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> nil, err
}
}
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> d.Auth == nil && d.Username != <span style="color: rgba(128, 0, 0, 1)">""</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> ok, auths := c.Extension(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">AUTH</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">); ok {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> strings.Contains(auths, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">CRAM-MD5</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">) {
d.Auth </span>=<span style="color: rgba(0, 0, 0, 1)"> smtp.CRAMMD5Auth(d.Username, d.Password)
} </span><span style="color: rgba(0, 0, 255, 1)">else</span> <span style="color: rgba(0, 0, 255, 1)">if</span> strings.Contains(auths, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LOGIN</span><span style="color: rgba(128, 0, 0, 1)">"</span>) &&
!strings.Contains(auths, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">PLAIN</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">) {
d.Auth </span>= &<span style="color: rgba(0, 0, 0, 1)">loginAuth{
username: d.Username,
password: d.Password,
host: d.Host,
}
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
d.Auth </span>= smtp.PlainAuth(<span style="color: rgba(128, 0, 0, 1)">""</span><span style="color: rgba(0, 0, 0, 1)">, d.Username, d.Password, d.Host)
}
}
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> d.Auth !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err = c.Auth(d.Auth); err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
c.Close()
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> nil, err
}
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span> &<span style="color: rgba(0, 0, 0, 1)">smtpSender{c, d}, nil
}
func (d </span>*Dialer) tlsConfig() *<span style="color: rgba(0, 0, 0, 1)">tls.Config {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> d.TLSConfig ==<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> &<span style="color: rgba(0, 0, 0, 1)">tls.Config{ServerName: d.Host}
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> d.TLSConfig
}
func addr(host </span><span style="color: rgba(0, 0, 255, 1)">string</span>, port <span style="color: rgba(0, 0, 255, 1)">int</span>) <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> fmt.Sprintf(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">%s:%d</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, host, port)
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> DialAndSend opens a connection to the SMTP server, sends the given emails and
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> closes the connection.</span>
func (d *Dialer) DialAndSend(m ...*<span style="color: rgba(0, 0, 0, 1)">Message) error {
s, err :</span>=<span style="color: rgba(0, 0, 0, 1)"> d.Dial()
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> err
}
defer s.Close()
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Send(s, m...)
}
type smtpSender </span><span style="color: rgba(0, 0, 255, 1)">struct</span><span style="color: rgba(0, 0, 0, 1)"> {
smtpClient
d </span>*<span style="color: rgba(0, 0, 0, 1)">Dialer
}
func (c </span>*smtpSender) Send(<span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(0, 0, 255, 1)">string</span>, to []<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">, msg io.WriterTo) error {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err := c.Mail(<span style="color: rgba(0, 0, 255, 1)">from</span>); err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err ==<span style="color: rgba(0, 0, 0, 1)"> io.EOF {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> This is probably due to a timeout, so reconnect and try again.</span>
sc, derr :=<span style="color: rgba(0, 0, 0, 1)"> c.d.Dial()
</span><span style="color: rgba(0, 0, 255, 1)">if</span> derr ==<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> s, ok := sc.(*<span style="color: rgba(0, 0, 0, 1)">smtpSender); ok {
</span>*c = *<span style="color: rgba(0, 0, 0, 1)">s
</span><span style="color: rgba(0, 0, 255, 1)">return</span> c.Send(<span style="color: rgba(0, 0, 255, 1)">from</span><span style="color: rgba(0, 0, 0, 1)">, to, msg)
}
}
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> err
}
</span><span style="color: rgba(0, 0, 255, 1)">for</span> _, addr :=<span style="color: rgba(0, 0, 0, 1)"> range to {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err := c.Rcpt(addr); err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> err
}
}
w, err :</span>=<span style="color: rgba(0, 0, 0, 1)"> c.Data()
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> err
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> _, err = msg.WriteTo(w); err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
w.Close()
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> err
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> w.Close()
}
func (c </span>*<span style="color: rgba(0, 0, 0, 1)">smtpSender) Close() error {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> c.Quit()
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Stubbed out for tests.</span>
<span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)"> (
netDialTimeout </span>=<span style="color: rgba(0, 0, 0, 1)"> net.DialTimeout
tlsClient </span>=<span style="color: rgba(0, 0, 0, 1)"> tls.Client
smtpNewClient</span>= func(conn net.Conn, host <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">) (smtpClient, error) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> smtp.NewClient(conn, host)
}
)
type smtpClient </span><span style="color: rgba(0, 0, 255, 1)">interface</span><span style="color: rgba(0, 0, 0, 1)"> {
Hello(</span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">) error
Extension(</span><span style="color: rgba(0, 0, 255, 1)">string</span>) (<span style="color: rgba(0, 0, 255, 1)">bool</span>, <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">)
StartTLS(</span>*<span style="color: rgba(0, 0, 0, 1)">tls.Config) error
Auth(smtp.Auth) error
Mail(</span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">) error
Rcpt(</span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">) error
Data() (io.WriteCloser, error)
Quit() error
Close() error
}</span></pre>
</div>
<p> DialAndSend ,首先调用Dial方法创建连接,然后发送邮件,最后关闭链接,如果要频繁发邮件,那么是否保持长连接更好了?这里的Dial 调用了smtp.NewClient 创建smtp.Client对象c,然后调用c.Hello ,c.Auth,send 实际是调用c.Mail,c.Rcpt,c.Data,那么我们可以自己调用Dial方法 然后循环调用send方法,最后在close。</p>
<p>代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">func SendMailByGomailTwo() {
d :</span>= gomail.NewDialer(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">smtp.163.com</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 128, 1)">25</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">dz45693@163.com</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"xxx</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
m :</span>=<span style="color: rgba(0, 0, 0, 1)"> gomail.NewMessage()
m.SetAddressHeader(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">From</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">dz45693@163.com</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">dz45693</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
m.SetHeader(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">To</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">dz45693@sina.com</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
m.SetHeader(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Subject</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">hello SendMailByGomailtwo!</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
m.Embed(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">d:\\Downloads\\1.png</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
m.SetBody(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">text/html</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">此处为正文121333!SendMailByGomailtwo</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
s, err :</span>=<span style="color: rgba(0, 0, 0, 1)"> d.Dial()
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
panic(err)
}
defer s.Close()
err </span>=<span style="color: rgba(0, 0, 0, 1)"> gomail.Send(s, m)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
panic(err)
}
m.Reset()
m.SetAddressHeader(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">From</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">dz45693@163.com</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">dz45693</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
m.SetHeader(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">To</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">dz45693@sina.com</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
m.SetHeader(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Subject</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">hello SendMailByGomailthree!</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
m.Embed(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">d:\\Downloads\\2.png</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
m.SetBody(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">text/html</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">此处为正文1SendMailByGomailthreeSendMailByGomailthree!</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
err </span>=<span style="color: rgba(0, 0, 0, 1)"> gomail.Send(s, m)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
panic(err)
}
}</span></pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2022.cnblogs.com/blog/209993/202203/209993-20220313210346649-2056745953.png"></p>
<p> </p>
</div>
<div id="MySignature" role="contentinfo">
windows技术爱好者<br><br>
来源:https://www.cnblogs.com/majiang/p/16001409.html
頁:
[1]