C#发送邮件遇operation timedout问题求助(附测试代码)
解决Gmail SMTP发送超时(operation timed out)的问题
我之前折腾Gmail SMTP的时候也遇到过一模一样的超时问题,咱们从几个关键点一步步排查解决:
1. 最核心的原因:Gmail不再支持普通密码登录SMTP
现在Google对账号安全管控很严,不管你有没有开两步验证,直接用原密码登录SMTP基本都会被拦截:
- 如果你的账号开了两步验证:必须在Google账号的「安全」设置里创建一个应用专用密码(App Password),把代码里的
"Password"替换成这个专用密码 - 如果没开两步验证:现在Google已经移除了“允许不太安全的应用”选项,还是得先开两步验证再创建应用专用密码
2. 检查网络是否能连通Gmail的SMTP端口
很多公司、校园或者公共网络会拦截587端口,你可以先测试连通性:
- 打开命令提示符(CMD),输入:
telnet smtp.gmail.com 587 - 如果弹出空白窗口,说明端口能连通;如果提示“无法打开连接”,那就是网络被拦截了,试试换手机热点或者联系网管开放端口
3. 必须加异常捕获!你的代码没处理异常导致直接中断
你现在的代码没有try-catch块,当smtp.Send(msg)抛出超时异常时,程序直接崩溃,后面的MessageBox.Show根本没机会执行。修改后的代码应该加上异常处理,还能帮你看到更详细的错误信息:
private void Form_Load(object sender, EventArgs e) { try { MailMessage msg = new MailMessage("teunenrichard@gmail.com", "ipadcraze@hotmail.com", "Movies this month", "Hello this is a test mail"); msg.IsBodyHtml = false; SmtpClient smtp = new SmtpClient("smtp.gmail.com", 587); smtp.UseDefaultCredentials = false; // 替换成你的应用专用密码 NetworkCredential xre = new System.Net.NetworkCredential("teunenrichard@gmail.com", "你的应用专用密码"); smtp.DeliveryMethod = SmtpDeliveryMethod.Network; smtp.Credentials = xre; smtp.EnableSsl = true; // 可以适当延长超时时间,默认是100秒 smtp.Timeout = 300000; // 5分钟 smtp.Send(msg); MessageBox.Show("mail sent"); } catch (Exception ex) { MessageBox.Show($"发送失败:{ex.Message}\n详细错误:{ex.ToString()}"); } }
4. 备选方案:改用更可靠的MailKit库
微软已经标记SmtpClient为过时API了,推荐使用第三方库MailKit,它对Gmail的支持更稳定:
- 先通过NuGet安装MailKit:
Install-Package MailKit - 然后用下面的代码发送:
using MailKit.Net.Smtp; using MimeKit; private void Form_Load(object sender, EventArgs e) { try { var message = new MimeMessage(); message.From.Add(new MailboxAddress("Sender", "teunenrichard@gmail.com")); message.To.Add(new MailboxAddress("Recipient", "ipadcraze@hotmail.com")); message.Subject = "Movies this month"; message.Body = new TextPart("plain") { Text = "Hello this is a test mail" }; using (var client = new SmtpClient()) { client.Connect("smtp.gmail.com", 587, true); // 用应用专用密码登录 client.Authenticate("teunenrichard@gmail.com", "你的应用专用密码"); client.Send(message); client.Disconnect(true); } MessageBox.Show("mail sent"); } catch (Exception ex) { MessageBox.Show($"发送失败:{ex.Message}\n详细错误:{ex.ToString()}"); } }
先优先试前两个步骤,尤其是应用专用密码的设置,这大概率是你遇到的问题。如果还是不行,用异常捕获里的详细信息来进一步定位问题。
内容的提问来源于stack exchange,提问作者Richard Teunen
相关产品推荐
相关产品推荐

