Golang的smtp.SendMail是阻塞的。

huangapple go评论79阅读模式
英文:

Golang smtp.SendMail blocking

问题

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

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

英文:

I tried to use smtp.SendMail() in a go program.
However it blocks and doesn't return until it times out.
This prevents me from finding out what is wrong.

My code:

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")
}

After a long time I get the following error:

<!-- language: lang-none -->

dial tcp 213.165.67.124:25: connection timed out

Any ideas what might be the real problem?

答案1

得分: 2

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

现在你可以使用TLS来拨号SMTP服务器,这样就不会阻塞了。详细信息请参考示例代码,或者使用非TLS端口。

SendMailTLS函数连接到地址为addr的服务器,默认使用TLS。

希望这些信息对你有帮助!

英文:

SendMail dial smtp server uses non-tls tcp connection, maybe your smtp server default uses tcp connection with ssl, not support STARTTLS extension. Client send STARTTLS commond and server will not reply, so now is blocking.

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

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

Now you can dail smtp server with tls and this is not blocking, detail see
example code, or use non-tls port.

// 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 := &amp;tls.Config{ServerName: host}
	if err = validateLine(from); err != nil {
		return err
	}
    ......
	conn, err := tls.Dial(&quot;tcp&quot;, addr, tlsconfig)
	if err != nil {
		return err
	}
	defer conn.Close()
	c, err := smtp.NewClient(conn, host)
    ......

答案2

得分: 0

如果您遇到超时问题,可以尝试直接使用net.Dial来验证连接:

conn, err := net.Dial("tcp", "smtp.web.de:25")
if err != nil {
    fmt.Println(err)
}

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

英文:

If you are seeing a timeout you can try using net.Dial directly to verify connectivity :

conn, err := net.Dial(&quot;tcp&quot;, &quot;smtp.web.de:25&quot;)
if err != nil {
	fmt.Println(err)
}

If that is not connecting then there is something local blocking the socket. Ask you local network guys about the firewall setup or if there are any network proxy type devices intercepting the outgoing traffic.

答案3

得分: -3

我很确定在路由器级别上,任何通过端口:25传输的内容都会被阻止,所以你需要更改你的路由器或服务器提供商的设置。

英文:

I'm pretty sure anything that goes by on port :25 is blocked on a router level, so you will have to change your router or server providers settings.

huangapple
  • 本文由 发表于 2013年10月7日 00:01:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/19210842.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定