C# SMTP 套接字问题

标签 c# sockets ssl smtp

我正在编写一个测试电子邮件地址的应用程序,其中一部分我需要向电子邮件地址发送少量数据以完全验证它,我目前正在使用套接字来完成此操作。

在我进行测试时,我使用 friend 的 SMTP 服务器进行测试,我的套接字工作正常,但是当我在大型电子邮件提供商(gmail、hotmail 等)上尝试同样的事情时,它却一无所获。

现在我得出的结论是,这与身份验证和安全相关,因此我测试了使用 SmtpClient 中内置的 .Nets 向 gmail 发送消息,并使用 SslEnabled 向其提供各种邮件对象,并为其提供所需的凭据,这继续进行工作。

我需要完成的是:

发送此数据而无需提供纯粹作为交换的登录详细信息。 也是一种将 Ssl 安全性整合到我的套接字中的方法。

任何有关这方面的帮助都将非常有用,我们将不胜感激!下面的代码...

    /// <summary>
    /// Opens up the socket and begins trying to connect to the provided domain
    /// </summary>
    /// <param name="domain">The domain listening on SMTP ports</param>
    /// <param name="recipient">The email recipient</param>
    /// <returns>Bool verifying success</returns>
    public static bool ActivateSocket(string domain, string recipient)
    {
        //X509Certificate cert = new X509Certificate();

        //Prepare our first command
        string SMTPcommand = "HELO www.codegremlin.co.uk\r\n";
        Encoding ASCII = Encoding.ASCII;
        //convert to byte array and get the buffers ready
        Byte[] ByteCommand = ASCII.GetBytes(SMTPcommand);
        Byte[] RecvResponseCode = new Byte[3];
        Byte[] RecvFullMessage = new Byte[256];
        //method response value
        bool TransactionSuccess = false;



        try
        {
            // do all of this outside so its fresh after every iteration
            Socket s = null;
            IPEndPoint hostEndPoint;
            IPAddress hostAddress = null;
            int conPort = 587;

            // get all the ip's assosciated with the domain
            IPHostEntry hostInfo = Dns.GetHostEntry(domain);
            IPAddress[] IPaddresses = hostInfo.AddressList;

            // go through each ip and attempt a connection
            for (int index = 0; index < IPaddresses.Length; index++)
            {
                hostAddress = IPaddresses[index];
                // get our end point
                hostEndPoint = new IPEndPoint(hostAddress, conPort);

                // prepare the socket
                s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                s.ReceiveTimeout = 2000;
                s.SendTimeout = 4000;
                try { s.Connect(hostEndPoint); }
                catch { Console.WriteLine("Connection timed out..."); }

                if (!s.Connected)
                {
                    // Connection failed, try next IPaddress.
                    TransactionSuccess = false;
                    s = null;
                    continue;
                }
                else
                {
                    // im going through the send mail, SMTP proccess here, slightly incorrectly but it
                    //is enough to promote a response from the server

                    s.Receive(RecvFullMessage);
                    Console.WriteLine(ASCII.GetString(RecvFullMessage));

                    s.Send(ByteCommand, ByteCommand.Length, 0);
                    s.Receive(RecvFullMessage);
                    Console.WriteLine(ASCII.GetString(RecvFullMessage));

                    ByteCommand = ASCII.GetBytes("MAIL FROM:mamooo@gmail.com\r\n");
                    s.Send(ByteCommand, ByteCommand.Length, 0);
                    s.Receive(RecvFullMessage);
                    Console.WriteLine(ASCII.GetString(RecvFullMessage));

                    ByteCommand = ASCII.GetBytes("RCPT TO:MatthewArnold@ccoder.co.uk\r\n");
                    s.Send(ByteCommand, ByteCommand.Length, 0);
                    s.Receive(RecvFullMessage);
                    Console.WriteLine(ASCII.GetString(RecvFullMessage));

                    ByteCommand = ASCII.GetBytes("DATA\r\n");
                    s.Send(ByteCommand, ByteCommand.Length, 0);
                    s.Receive(RecvFullMessage);
                    Console.WriteLine(ASCII.GetString(RecvFullMessage));

                    ByteCommand = ASCII.GetBytes("this email was sent as a test!\r\n.\r\n");
                    s.Send(ByteCommand, ByteCommand.Length, 0);
                    s.Receive(RecvFullMessage);
                    Console.WriteLine(ASCII.GetString(RecvFullMessage));

                    ByteCommand = ASCII.GetBytes("SEND\r\n");
                    s.Send(ByteCommand, ByteCommand.Length, 0);
                    s.Receive(RecvFullMessage);
                    Console.WriteLine(ASCII.GetString(RecvFullMessage));

                    ByteCommand = ASCII.GetBytes("QUIT\r\n");
                    s.Send(ByteCommand, ByteCommand.Length, 0);
                    s.Receive(RecvFullMessage);
                    Console.WriteLine(ASCII.GetString(RecvFullMessage));

                    int i = 0;
                    TransactionSuccess = true;
                }

            }


        }

        catch (SocketException e)
        {
            Console.WriteLine("SocketException caught!!!");
            Console.WriteLine("Source : " + e.Source);
            Console.WriteLine("Message : " + e.Message);
        }
        catch (ArgumentNullException e)
        {
            Console.WriteLine("ArgumentNullException caught!!!");
            Console.WriteLine("Source : " + e.Source);
            Console.WriteLine("Message : " + e.Message);
        }
        catch (NullReferenceException e)
        {
            Console.WriteLine("NullReferenceException caught!!!");
            Console.WriteLine("Source : " + e.Source);
            Console.WriteLine("Message : " + e.Message);
        }
        catch (Exception e)
        {
            Console.WriteLine("Exception caught!!!");
            Console.WriteLine("Source : " + e.Source);
            Console.WriteLine("Message : " + e.Message);
        }

        return TransactionSuccess;

    }

最佳答案

您究竟为什么要尝试自己实现此功能?

您应该重用现有的 SMTP 实现,否则您永远无法获得正确实现的众多 RFC 的所有细节。

我建议您再看看 SmtpClient 类,因为它似乎完全符合您的要求。

还有一件事:您知道一个事实,您需要与 gmail 地址通信的 SMTP 服务器不是 gmail.com,对吗?您需要从 gmail.com 的 DNS 检索 MX 记录并连接到其中一个记录。

除此之外,您不应该直接连接到任何 SMTP 来传送邮件。如果服务器实现灰名单和其他反垃圾邮件技术,您将不会成功。依靠系统上的 MTA 发送电子邮件。如果您执行此操作以检查电子邮件地址的正确性,则需要提供一个有效的发件人地址并检查该邮箱是否有来自您的 MTA 的退回邮件。

关于C# SMTP 套接字问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1722463/

相关文章:

c# - MySQL -> 事务上下文 -> 代码审查

c# - 统一: Record video from device camera

c - 已接受来自 00 :00:00:00:00:00; after connect 的连接

ssl - Apache : cURL: ssl3_get_record:wrong version number for apache2 ssl

由于 SSL 错误,RubyGems 在 Windows 7 上根本无法运行

c# - Web 服务返回 xml 尽管返回格式是 json

c# - 根据另一个数组中指定的索引从数组中选择元素c#

Java Serversocket不接受连接

java - 在套接字中发送停止消息

firefox - 如何使用 Selenium 禁用 Firefox 的不可信连接警告?