smtp - Golang smtp.SendMail 阻塞

标签 smtp go

我尝试在 go 程序中使用 smtp.SendMail()。 但是它会阻塞并且在超时之前不会返回。 这使我无法找出问题所在。

我的代码:

to := []string{"recepient@example.com"}
err := smtp.SendMail("smtp.web.de:25", smtp.CRAMMD5Auth("example@web.de", "password"), "example@web.de", to, []byte("hi"))
if err != nil {
    fmt.Println(err)
}else{
    fmt.Println("Success")
}

很长一段时间后,我收到以下错误:

dial tcp 213.165.67.124:25: connection timed out

有什么想法可能是真正的问题吗?

最佳答案

SendMail 拨号smtp 服务器使用非tls tcp 连接,可能你的smtp 服务器默认使用tcp 连接ssl,不支持STARTTLS 扩展。客户端发送 STARTTLS commond,服务器不会回复,所以现在是阻塞的。

func SendMail(addr string, a Auth, from string, to []string, msg []byte) error {
    ......

    if ok, _ := c.Extension("STARTTLS"); ok {
        config := &tls.Config{ServerName: c.serverName}
        if testHookStartTLS != nil {
            testHookStartTLS(config)
        }
        if err = c.StartTLS(config); err != nil {
            return err
        }
    }
    ......
}

现在你可以使用 tls 访问 smtp 服务器并且这不是阻塞的,详情参见 example code , 或者使用非 tls 端口。

// SendMailTLS connects to the server at addr, default use TLS
func SendMailTLS(addr string, auth smtp.Auth, from string, to []string, msg []byte) error {
    ......
    tlsconfig := &tls.Config{ServerName: host}
    if err = validateLine(from); err != nil {
        return err
    }
    ......
    conn, err := tls.Dial("tcp", addr, tlsconfig)
    if err != nil {
        return err
    }
    defer conn.Close()
    c, err := smtp.NewClient(conn, host)
    ......

关于smtp - Golang smtp.SendMail 阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19210842/

相关文章:

java - 没有收到电子邮件

email - return-path、reply-to 和 from 之间的行为差​​异是什么?

asp.net - VB.Net MailMessage文本编码问题

docker - 如何正确配置 Dockerfile 以在 Google Cloud Run 上运行?

reflection - golang reflect如何判断零值

javascript - 如何以数组形式访问 JavaScript 对象

python - 使用 Python 检查电子邮件是否真实

Azure 网站 Elmah SMTP 邮件在部署时无法工作

go - 在 SDL Go 程序中复制纹理时出现运行时 panic

struct - 如何在 slice 内设置结构的字段?