Проблемы с сокетом SMTP в C # - PullRequest
1 голос
/ 12 ноября 2009

Я пишу приложение, которое проверяет адреса электронной почты, для одной части этого мне нужно отправить небольшой объем данных на адрес электронной почты, чтобы полностью его проверить, в настоящее время я использую сокеты для этого.

Во время тестирования я использовал SMTP-сервер друзей для тестирования, и мой сокет работал нормально, но когда я попробовал то же самое на большом почтовом провайдере (gmail, hotmail и т. Д.), У него его не было.

Теперь я пришел к выводу, что это связано с аутентификацией и безопасностью, поэтому я протестировал отправку сообщения в gmail с использованием .Nets, встроенного в SmtpClient, и различных объектов Mail с использованием 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;

    }

1 Ответ

2 голосов
/ 12 ноября 2009

Почему именно вы пытаетесь реализовать эту функцию самостоятельно?

Вам следует повторно использовать существующую реализацию SMTP, в противном случае вы никогда не получите все подробности о правильно реализованных многочисленных RFC.

Я предлагаю вам еще раз взглянуть на класс SmtpClient, поскольку он, кажется, делает именно то, что вы хотите.

Есть еще одна вещь: вы знаете о том факте, что SMTP-сервер, с которым вам нужно общаться для адресов gmail, не является gmail.com, верно? Вам нужно получить записи MX из DNS для gmail.com и подключиться к одной из них.

Кроме того, вам не нужно подключаться к SMTP-серверу напрямую для доставки почты. У вас ничего не получится, если на сервере реализованы списки рассылки и другие методы борьбы со спамом. Положитесь на MTA в вашей системе для отправки электронной почты. Если вы реализуете это для проверки правильности адресов электронной почты, вам нужно предоставить рабочий адрес FROM и проверить этот почтовый ящик на наличие отказов от вашего MTA.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...