Golang smtp.SendMail 阻塞

5

我尝试在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

任何想法可能是真正的问题?

1
阻塞如何防止您进行调试?我无法重现此行为,我得到了“530需要身份验证”。您是否尝试使用数据包嗅探器跟踪流量? - nemo
关于嗅探:它似乎使用了TLS,这使我无法看到正在发生的事情。(Wireshark报告TLSv1客户端密钥交换等)关于调试:我不确定如何让SendMail打印其发送/接收的内容。 - user2089648
1
@user2089648,请查看http://sendmail.org/~ca/email/doc8.12/op-sh-3.html下的“调试”部分。 - Intermernet
5
如果它在25号端口上,则直到发出STARTTLS命令之前,它将以明文形式显示。你可能在嗅探错误的流量。无论如何,“连接超时”意味着一件特定的事情-(TCP)连接超时,即数据包未到达smtp.web.de或您未收到其响应。很可能不是一个golang问题。 - Brad Peabody
2
尝试使用net.Dial("tcp", "smtp.web.de:25")。我敢打赌你的ISP正在阻止端口25。 - Russ Cox
显示剩余2条评论
3个回答

2

SendMail 拨号 SMTP 服务器使用的是非 TLS 的 TCP 连接,可能你的 SMTP 服务器默认使用带有 SSL 的 TCP 连接,不支持 STARTTLS 扩展。客户端发送 STARTTLS 命令,但服务器没有回复,因此现在被阻塞。

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服务器,这不会被阻止。具体请参见示例代码,或使用非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)
    ......

0
如果您看到超时错误,可以尝试直接使用net.Dial验证连接:
conn, err := net.Dial("tcp", "smtp.web.de:25")
if err != nil {
    fmt.Println(err)
}

如果连接不上,那么可能是本地阻止了套接字。请向您的本地网络管理员询问防火墙设置或是否有任何网络代理类型设备拦截出站流量。

-4
我相信任何通过25号端口传输的东西都会被路由器屏蔽,所以你需要更改你的路由器或服务器提供商的设置。

2
那不是真的。25端口是用于SMTP邮件的。 - ashishmaurya
如果您在住宅网络中,则不允许运行该程序。但是,如果您通过SSH登录到服务器并运行该程序,则应该可以正常工作。 - RonnieKritou
1
你似乎在谈论你的本地设置,而不是针对OP的一般性答案。 - LenW

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接