我无法发送电子邮件

I can't send an e-mail

我尝试过不同的端口,如 25、587,我尝试将服务器更改为本地主机并将 UseDefaultCredentials 设置为 falsessl 为 false。

还是不行。它给了我一个错误:"Email send failure".

private void button4_Click(object sender, EventArgs e)
    {
        try
        {
            MailMessage myMsg = new MailMessage();
            myMsg.From = new MailAddress("@yahoo.com");
            myMsg.To.Add("@yahoo.com");
            myMsg.Subject = "Subject " + textBox1.Text;
            myMsg.Body = "Body " + textBox2.Text;

            // your remote SMTP server IP.
            SmtpClient smtp = new SmtpClient("smtp.mail.yahoo.com");
            smtp.Port = 465;
            smtp.UseDefaultCredentials = false;
            smtp.Credentials = new System.Net.NetworkCredential("@yahoo.com", "psw");
            smtp.EnableSsl = true;
            smtp.Send(myMsg);

        }
        catch (SmtpException ex)
        {
            MessageBox.Show("E-mail unsuccesful "+ ex);
        }
    }

我制作了一个class来测试 SMTP 发送

    class SmtpTests
    {

        //Normal port 25 text,465 SSL,587 text thn STARTSSL

        protected static log4net.ILog Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        static int connectionTimeout = 1300;

        /// <summary>
        /// Tests the SMTP server and try to send a test Email
        /// </summary>
        /// <param name="login"></param>
        /// <param name="password"></param>
        /// <param name="server">Server DNS name</param>
        /// <param name="port"></param>
        /// <param name="forceSsl"></param>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="msg">Message to send to the body</param>
        /// <param name="log">Detailed Log</param>
        /// <param name="resume">Resumed Log</param>
        /// <param name="error">Erro Log</param>
        /// <param name="checkcertificate">Check if SSL Certificate in the Server is acceptable</param>
        /// <param name="trystartssl">try to send the command STARTTLS</param>
        /// <returns></returns>
        public static bool ScanSMTP(string login, string password, string server, int port, bool forceSsl,
            string from, string to, string msg,
            out string log, out string resume, out string error,
            bool checkcertificate = true, bool trystartssl = true)
        {

            #region check parameters

            log = Environment.NewLine;
            error = "";
            resume = "";
            string _fromaddrstr = "";
            string _toaddrstr = "";

            string _errorResume = $"[FAIL] Port={port}, Force SSL={forceSsl}, try STARTSSL={trystartssl}";

            System.Net.Mail.MailAddress addr = null;

            if (!String.IsNullOrEmpty(login))
            {
                if (String.IsNullOrEmpty(password))
                {
                    error = "If login is not empty than the password cannot be empty";
                    log += "!! Error : " + error;
                    resume = Environment.NewLine + $"[FAIL] 'password' is missing" + Environment.NewLine;
                    return false;
                }
            }

            try
            {
                addr = new System.Net.Mail.MailAddress(from);
                _fromaddrstr = addr.Address;
            }
            catch
            {
                error = "'from' email address is incorrect.";
                log += "!! Error : " + error;
                resume = Environment.NewLine + $"[FAIL] 'from' incorrect format > '{from}'" + Environment.NewLine;
                return false;
            }

            try
            {
                addr = new System.Net.Mail.MailAddress(to);
                _toaddrstr = addr.Address;
            }
            catch
            {
                error = "'to' email address is incorrect.";
                log += "!! Error : " + error;
                resume = Environment.NewLine + $"[FAIL] 'to' incorrect format > '{to}'" + Environment.NewLine;
                return false;
            }



            #endregion

            try
            {
                #region support variables

                string _response = "";
                string _msgfotter = "";

                StreamReader clearTextReader = null;
                StreamWriter clearTextWriter = null;

                StreamReader sslreader = null;
                StreamWriter sslwriter = null;

                SslStream sslStream = null;

                // Depending on checkcertificate value stream may ignore Certificate Errors
                // like: Hostname not in the certificate and Certificate Chain Errors 
                SslStream GetSslStream(Stream innerstream)
                {
                    if (checkcertificate)
                        return new SslStream(innerstream);
                    else
                        return new SslStream(
                            innerstream,
                            false,
                            new RemoteCertificateValidationCallback((s, c, h, e) => true),
                            null
                    );
                }

                #endregion

                #region support internal methods

                void ExitError(string str, ref string _log, ref string _error)
                {
                    _error = str;
                    _log += "!! Error : " + str + Environment.NewLine + Environment.NewLine;
                    if (sslStream == null)
                    {
                        clearTextWriter.WriteLine("QUIT");
                    }
                    else
                    {
                        sslwriter.WriteLine("QUIT");
                    }


                }

                string AskReceive(string commandline, ref string _log)
                {
                    if (sslStream == null)
                    {
                        _log += "> " + commandline + Environment.NewLine;
                        clearTextWriter.WriteLine(commandline);

                        string _str;

                        System.Threading.Thread.Sleep(200);

                        //while (!clearTextReader.EndOfStream)
                        //while (!String.IsNullOrEmpty(_str))
                        //    {
                        //    System.Threading.Thread.Sleep(200);
                        //    //yield return _str;
                        //    _str = clearTextReader.ReadLine();
                        //    _log += "< " + _str + Environment.NewLine;
                        //}
                        _str = clearTextReader.ReadLine();
                        _log += "< " + _str + Environment.NewLine;

                        return _str;
                    }
                    else
                    {
                        _log += "> " + commandline + Environment.NewLine;
                        sslwriter.WriteLine(commandline);
                        System.Threading.Thread.Sleep(200);
                        string _str = sslreader.ReadLine();
                        _log += "< " + _str + Environment.NewLine;
                        return _str;
                    }
                }

                bool Login(ref string _log, ref string _error)
                {
                    if (!(_response = AskReceive($"AUTH LOGIN", ref _log)).StartsWith("334"))
                    {
                        ExitError(_response, ref _log, ref _error);
                        return false;
                    }

                    if (!(_response = AskReceive(Convert.ToBase64String(Encoding.UTF8.GetBytes($"{login}")), ref _log)).StartsWith("334"))
                    {
                        ExitError(_response, ref _log, ref _error);
                        return false;
                    }

                    if (!(_response = AskReceive(Convert.ToBase64String(Encoding.UTF8.GetBytes($"{password}")), ref _log)).StartsWith("235"))
                    {
                        ExitError(_response, ref _log, ref _error);
                        return false;
                    }

                    return true;
                }

                bool SendMsg(ref string _log, ref string _error)
                {

                    // HELO JakesDominoApp
                    // MAIL FROM: jake@jakehowlett.com
                    // RCPT To: jhowlett@EITS
                    // DATA
                    // From: My Self <me@you.com>
                    // To: A secret list <you@me.com>
                    // Subject: A simple test
                    // Mime-Version: 1.0;
                    // Content-Type: text/html; charset="ISO-8859-1";
                    // Content-Transfer-Encoding: 7bit;
                    //
                    // <html>
                    // <body>
                    // <h2>An important link to look at!</h2>
                    // Here's an <a href="http://www.codestore.net">important link</a>
                    // </body>
                    // </html>
                    // .
                    // QUIT

                    if (!String.IsNullOrEmpty(login))
                        if (!Login(ref _log, ref _error))
                            return false;


                    if (!(_response = AskReceive($"MAIL FROM: <{_fromaddrstr}>", ref _log)).StartsWith("250"))
                    {
                        ExitError(_response, ref _log, ref _error);
                        return false;
                    }

                    if (!(_response = AskReceive($"RCPT TO: <{_toaddrstr}>", ref _log)).StartsWith("250"))
                    {
                        ExitError(_response, ref _log, ref _error);
                        return false;
                    }

                    string _return = AskReceive($"DATA", ref _log);

                    if (_return.Substring(0, 1) == "5")
                    {
                        ExitError(_return, ref _log, ref _log);
                        return false;
                    }

                    string _details = $"Server:'{server}' | Login:'{login}' | port:{port} | try STARTTSL:{trystartssl} | Force SSL:{forceSsl}";

                    if (!AskReceive(
                        $"From: {from}" + Environment.NewLine +
                        $"To: {to}" + Environment.NewLine +
                        $"Subject: " + _details +
                        Environment.NewLine + Environment.NewLine +
                        msg + Environment.NewLine + Environment.NewLine +
                        "__________________________________________________" + Environment.NewLine + Environment.NewLine +
                        _details + " " + _msgfotter + Environment.NewLine +
                        Environment.NewLine + Environment.NewLine + ".", ref _log).StartsWith("250"))
                    {
                        ExitError(_response, ref _log, ref _error);
                        return false;
                    }

                    AskReceive($"QUIT", ref _log);
                    return true;

                }

                #endregion

                #region method body

                TcpClient client = new TcpClient();

                //Make the connection with timeout
                if (!client.ConnectAsync(server, port).Wait(connectionTimeout))
                {
                    //log = ex.ExceptionToString();
                    error = $"Could not connect '{server}' at port '{port}'";
                    log += Environment.NewLine + error + Environment.NewLine;
                    resume = Environment.NewLine + $"[FAIL] Port={port}. Could not connect '{server}' at port '{port}'" + Environment.NewLine;
                    return false;
                }

                using (client)
                {

                    if (forceSsl)
                    {
                        using (NetworkStream stream = client.GetStream())
                        using (sslStream = GetSslStream(stream)) // new SslStream(stream))
                        {
                            sslStream.AuthenticateAsClient(server);

                            using (sslreader = new StreamReader(sslStream))
                            using (sslwriter = new StreamWriter(sslStream) { AutoFlush = true })
                            {
                                log += Environment.NewLine + Environment.NewLine + "## SSL connection (safe)" + Environment.NewLine;
                                string connectResponse = sslreader.ReadLine();
                                log += "< " + connectResponse + Environment.NewLine;
                                if (!connectResponse.StartsWith("220"))
                                {
                                    ExitError(_response, ref log, ref error);
                                    resume = Environment.NewLine + $"[FAIL] Port={port}, Force SSL={forceSsl} (encrypted)";
                                    return false;
                                }

                                if (!(_response = AskReceive($"HELO {Dns.GetHostName()}", ref log)).StartsWith("250"))
                                {
                                    ExitError(_response, ref log, ref error);
                                    resume = Environment.NewLine + $"[FAIL] Port={port}, Force SSL={forceSsl} (encrypted)";
                                    return false;
                                }

                                _msgfotter = $"Encrypted MSG using SMTP/S on port: {port}";

                                if (SendMsg(ref log, ref error))
                                { resume = Environment.NewLine + $"[SUCCESS] Port={port}, Force SSL={forceSsl} (encrypted)"; return true; }
                                else
                                { resume = Environment.NewLine + $"[FAIL] Port={port}, Force SSL={forceSsl} (encrypted)"; return false; }
                            }
                        }
                    }
                    else //Not SMTP/S (SSL)
                    {
                        using (NetworkStream stream = client.GetStream())
                        using (clearTextReader = new StreamReader(stream))
                        using (clearTextWriter = new StreamWriter(stream) { AutoFlush = true })

                        {
                            log += Environment.NewLine + Environment.NewLine + "## Plain text connection (UNSAFE)" + Environment.NewLine;
                            string connectResponse = clearTextReader.ReadLine();
                            log += "< " + connectResponse + Environment.NewLine;
                            if (!connectResponse.StartsWith("220"))
                            {
                                ExitError(connectResponse, ref log, ref error);
                                resume = Environment.NewLine + $"[FAIL] Port={port}, Force SSL={forceSsl} (unsafe, plain text)";
                                return false;
                            }

                            if (!(_response = AskReceive($"HELO {Dns.GetHostName()}", ref log)).StartsWith("250"))
                            {
                                ExitError(_response, ref log, ref error);
                                resume = Environment.NewLine + $"[FAIL] Port={port}, Force SSL={forceSsl} (unsafe, plain text)";
                                return false;
                            }

                            if (trystartssl)
                            {
                                if ((_response = AskReceive("STARTTLS", ref log)).StartsWith("220"))
                                {
                                    clearTextReader = null;
                                    clearTextWriter = null;
                                    using (sslStream = GetSslStream(stream)) // new SslStream(stream))
                                    {

                                        //TLS Start
                                        sslStream.AuthenticateAsClient(server);
                                        log += Environment.NewLine + Environment.NewLine + "## TLS connection (safe)" + Environment.NewLine;
                                        using (sslreader = new StreamReader(sslStream))
                                        using (sslwriter = new StreamWriter(sslStream) { AutoFlush = true })
                                        {
                                            if (!AskReceive($"HELO {Dns.GetHostName()}", ref log).StartsWith("250"))
                                            { ExitError(_response, ref log, ref error); resume = $"[FAIL] Port={port}, Force SSL={forceSsl} (encrypted)"; return false; }

                                            _msgfotter = "Encrypted MSG using STARTSSL on port: " + port.ToString();
                                            if (SendMsg(ref log, ref error))
                                            {
                                                resume = Environment.NewLine +
                                                    $"[SUCCESS] Port={port}, Force SSL={forceSsl}, try STARTSSL={trystartssl} (encrypted)";
                                                return true;
                                            }
                                            else
                                            {
                                                resume = Environment.NewLine +
                                                    $"[FAIL] Port={port}, Force SSL={forceSsl}, try STARTSSL={trystartssl} (encrypted)";
                                                return false;
                                            }
                                        }
                                    }
                                }
                            }

                            if ((trystartssl && !_response.StartsWith("220")) || !trystartssl)
                            {

                                if (trystartssl)
                                    log += "## Does not accept StartSSL" + Environment.NewLine;

                                _msgfotter = "Unsafe MSG using plain text on port: " + port.ToString();

                                if (SendMsg(ref log, ref error))
                                {
                                    resume = Environment.NewLine +
                                        $"[SUCCESS] Port={port}, Force SSL={forceSsl}, try STARTSSL={trystartssl} (unsafe, plain text)";
                                    return true;
                                }
                                else
                                {
                                    resume = Environment.NewLine +
                                        $"[FAIL] Port={port}, Force SSL={forceSsl}, try STARTSSL={trystartssl} (unsafe, plain text)";
                                    return false;
                                }
                            }

                            return false;

                        }
                    }

                }

                #endregion

            }
            catch (Exception ex)
            {
                if (ex.Message == @"The remote certificate is invalid according to the validation procedure.")
                {
                    log += $"The host name '{server}' must exist in the server SSL certificate. Don't use IP or host names not in the Certificate" + Environment.NewLine;
                }
                error = ex.Message;
                log += "!! Error : " + ex.Message + Environment.NewLine;
                resume += Environment.NewLine + _errorResume;

                return false;
            }


        }


    }