【问题标题】:Sending emails from a windows forms application从 Windows 窗体应用程序发送电子邮件
【发布时间】:2012-06-07 22:28:13
【问题描述】:

我正在构建一个 Windows 窗体应用程序,它应该在远程/隔离机器上运行,并通过电子邮件向管理员发送错误通知。我尝试使用 System.Net.Mail 类来实现这一点,但我遇到了一个奇怪的问题:

1.我收到一条错误消息:

System.IO.IOException: Unable to read data from the transport connection: 
An existing connection was forcibly closed by the remote host.--->
System.Net.Sockets.SocketException: An existing connection was forcibly closed by 
the remote host at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, 
Int32 size, SocketFlags socketFlags) at System.Net.Sockets.NetworkStream.
Read(Byte[] buffer, Int32 offset, Int32 size)

2. 我尝试嗅探网络活动,看看出了什么问题。所以事情是这样的:

i) The DNS lookup for my SMTP server's hostname works
ii) My application connects to the SMTP server and sends "EHLO MY-HOSTNAME"
iii) SMTP server responds back with it's usual
iv) My application sends "AUTH login abcdxyz" and receives an acknowledgement packet

此时,似乎 SMTP 服务器似乎没有请求密码,或者我的机器在 SMTP 服务器请求密码之前关闭了与 SMTP 服务器的连接。

我尝试过使用不同的 SMTP 端口和 SMTP 主机。此外,我尝试禁用我的防火墙和 AV,但没有运气。使用 PuTTY 连接到我的 SMTP 服务器并发出与我的应用程序相同的命令序列(从数据包嗅探器中挑选)时,一切正常,我能够发送电子邮件。

这是我正在使用的代码:

Imports System.Net
Imports System.Net.Mail

Public Function SendMail() As Boolean

     Dim smtpClient As New SmtpClient("smtp.myserver.com", 587) 'I tried using different hosts and ports
     smtpClient.UseDefaultCredentials = False
     smtpClient.Credentials = New NetworkCredential("username@domain.com", "password")
     smtpClient.EnableSsl = True 'Also tried setting this to false

     Dim mm As New MailMessage
     mm.From = New MailAddress("username@domain.com")
     mm.Subject = "Test Mail"
     mm.IsBodyHtml = True
     mm.Body = "<h1>This is a test email</h1>"
     mm.To.Add("someone@domain.com")

     Try
          smtpClient.Send(mm)
          MsgBox("SUCCESS!")
     Catch ex As Exception
          MsgBox(ex.InnerException.ToString)
     End Try

     mm.Dispose()
     smtpClient.Dispose()

     Return True

End Function

有什么建议吗?

【问题讨论】:

  • 已将代码添加到我的帖子中...
  • 如果您使用此代码并使用您的 gmail 帐户凭据,例如,您会收到相同的错误吗?就像迪奥戈提到的......
  • 我尝试使用不同的连接,但似乎没有问题。至于我遇到问题的连接,我可以使用 telnet 连接到所有 SMTP 端口,但是当我的应用程序连接到 SMTP 服务器时,连接会断开。
  • 嘿,伙计,请参阅 SHAIKRAFFI 代码,您可以解决所有问题

标签: c# vb.net winforms smtpclient


【解决方案1】:

在 C# 中它是这样工作的:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void btnTest_Click(object sender, RoutedEventArgs e)
    {
        MailAddress from = new MailAddress("Someone@domain.topleveldomain", "Name and stuff");
        MailAddress to = new MailAddress("Someone@domain.topleveldomain", "Name and stuff");
        List<MailAddress> cc = new List<MailAddress>();
        cc.Add(new MailAddress("Someone@domain.topleveldomain", "Name and stuff"));
        SendEmail("Want to test this damn thing", from, to, cc);
    }

    protected void SendEmail(string _subject, MailAddress _from, MailAddress _to, List<MailAddress> _cc, List<MailAddress> _bcc = null)
    {
        string Text = "";
        SmtpClient mailClient = new SmtpClient("Mailhost");
        MailMessage msgMail;
        Text = "Stuff";
        msgMail = new MailMessage();
        msgMail.From = _from;
        msgMail.To.Add(_to);
        foreach (MailAddress addr in _cc)
        {
            msgMail.CC.Add(addr);
        }
        if (_bcc != null)
        {
            foreach (MailAddress addr in _bcc)
            {
                msgMail.Bcc.Add(addr);
            }
        }
        msgMail.Subject = _subject;
        msgMail.Body = Text;
        msgMail.IsBodyHtml = true;
        mailClient.Send(msgMail);
        msgMail.Dispose();
    }
}

不要忘记using System.Net.Mail;

我认为在VB中它是这样工作的,这是代码,它可能有一些错误,我不经常在vb.net中编写:

Private Sub btnTest_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
    Dim _from As New MailAddress("Someone@domain.topleveldomain", "Name and stuff")
    Dim _to As New MailAddress("Someone@domain.topleveldomain", "Name and stuff")
    Dim cc As New List(Of MailAddress)
    cc.Add(New MailAddress("Someone@domain.topleveldomain", "Name and stuff"))
    SendEmail("Wan't to test this thing", _from, _to, cc)
End Sub

Protected Sub SendEmail(ByVal _subject As String, ByVal _from As MailAddress, ByVal _to As MailAddress, ByVal _cc As List(Of MailAddress), Optional ByVal _bcc As List(Of MailAddress) = Nothing)

    Dim Text As String = ""
    Dim mailClient As New SmtpClient("Mailhost")
    Dim msgMail As MailMessage
    Text = "Stuff"
    msgMail = New MailMessage()
    msgMail.From = _from
    msgMail.To.Add(_to)
    For Each addr As MailAddress In _cc
        msgMail.CC.Add(addr)
    Next
    If _bcc IsNot Nothing Then
        For Each addr As MailAddress In _bcc
            msgMail.Bcc.Add(addr)
        Next
    End If
    msgMail.Subject = _subject
    msgMail.Body = Text
    msgMail.IsBodyHtml = True
    mailClient.Send(msgMail)
    msgMail.Dispose()
End Sub

别忘了导入System.Net.Mail

【讨论】:

  • 感谢 Thanatos,但这与我的代码或 Diogo 发布的内容没有太大区别。问题似乎是 SMTP 服务器在 Visual Studio 通过我正在使用的电缆连接连接到它时关闭了连接(使用相同的电缆连接和不同的 SMTP 或 Telnet 客户端连接到 SMTP 端口没有问题)。但如果我使用不同的连接(我的辅助是 3G)连接,Visual Studio 似乎没有任何问题。
  • 您是否尝试过使用 SendAsync 方法?当它是超时的原因时,它可能会起作用。 link 这是 MSDN 站点,它可能会对您有所帮助。 @紫山
【解决方案2】:
SendMail.CS Page

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Mail;

namespace SendMailUsingWindowsForms
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {

                //Sending the email.
                //Now we must create a new Smtp client to send our email.

                SmtpClient client = new SmtpClient("smtp.gmail.com", 25);   //smtp.gmail.com // For Gmail
                                                                            //smtp.live.com // Windows live / Hotmail
                                                                            //smtp.mail.yahoo.com // Yahoo
                                                                            //smtp.aim.com // AIM
                                                                            //my.inbox.com // Inbox


                //Authentication.
                //This is where the valid email account comes into play. You must have a valid email account(with password) to give our program a place to send the mail from.

                NetworkCredential cred = new NetworkCredential("*******@gmail.com", "........");

                //To send an email we must first create a new mailMessage(an email) to send.
                MailMessage Msg = new MailMessage();

                // Sender e-mail address.
                Msg.From = new MailAddress(textBox1.Text);//Nothing But Above Credentials or your credentials (*******@gmail.com)

                // Recipient e-mail address.
                Msg.To.Add(textBox2.Text);

                // Assign the subject of our message.
                Msg.Subject = textBox3.Text;

                // Create the content(body) of our message.
                Msg.Body = textBox4.Text;

                // Send our account login details to the client.
                client.Credentials = cred;

                //Enabling SSL(Secure Sockets Layer, encyription) is reqiured by most email providers to send mail
                client.EnableSsl = true;

                //Confirmation After Click the Button
                label5.Text = "Mail Sended Succesfully";

                // Send our email.
                client.Send(Msg);



            }
            catch
            {
                // If Mail Doesnt Send Error Mesage Will Be Displayed
                label5.Text = "Error";
            }
        }


    }
}

SendMail.Design

【讨论】:

  • 这在我使用端口 587 后适用于 Gmail,并且是在任何公司网络/防火墙之外进行的。
【解决方案3】:

尝试使用这个:

    public SmtpClient client = new SmtpClient();
    public MailMessage msg = new MailMessage();
    public System.Net.NetworkCredential smtpCreds = new System.Net.NetworkCredential("mail", "password");

    public void Send(string sendTo, string sendFrom, string subject, string body)
    {
        try
        {
            //setup SMTP Host Here
            client.Host = "smtp.gmail.com";
            client.Port = 587;
            client.UseDefaultCredentials = false;
            client.Credentials = smtpCreds;
            client.EnableSsl = true;

            //converte string to MailAdress

            MailAddress to = new MailAddress(sendTo);
            MailAddress from = new MailAddress(sendFrom);

            //set up message settings

            msg.Subject = subject;
            msg.Body = body;
            msg.From = from;
            msg.To.Add(to);

            // Enviar E-mail

            client.Send(msg);

        }
        catch (Exception error)
        {
            MessageBox.Show("Unexpected Error: " + error);
        }
    }

别忘了打电话:

using System.Net.Mail;
using System.Windows.Forms;

【讨论】:

  • 感谢 Diogo,但我认为这与我刚刚在上面发布的代码相同。不过,它不需要调用 System.Windows.Forms。
  • 这对我来说很好,尝试看看你的 smtp 配置是否正确。
猜你喜欢
  • 2013-03-10
  • 2020-05-29
  • 2016-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-04
  • 2021-06-08
  • 2020-05-24
相关资源
最近更新 更多