C#SMTP套接字问题

时间:2009-11-12 14:13:03

标签: c# sockets ssl smtp

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

虽然我在测试时使用了一个朋友的SMTP服务器进行测试,但我的套接字工作正常,但是当我在一个大型电子邮件提供商(gmail,hotmail等)上尝试过同样的事情时,它却没有。

现在我得出结论,这是与身份验证和安全性相关的,所以我测试了使用内置SmtpClient的.Nets和使用SslEnabled的各种Mail对象向gmail发送消息,并为其提供了它要求的凭据,这继续工作

我需要完成的是:

发送此数据而无需提供纯粹充当交换的登录详细信息。 也是一种将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;

    }

1 个答案:

答案 0 :(得分:2)

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

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

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

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

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