Подключение к smtp.live.com с классом TcpClient - PullRequest
5 голосов
/ 07 июня 2011

Я пытаюсь подключиться к smtp.live.com с помощью класса TcpClient.Вот замечательный пример подключения к Gmail: Тестирование SMTP-сервера выполняется через C #

К сожалению, при обновлении этого для работы с smtp.live.com я получаю "IOException: рукопожатие не удалось из-за непредвиденного формата пакета ", когда вызывается метод AuthenticateAsClient.

Как обойти это?

class Program
{
    static void Main(string[] args)
    {
        using (var client = new TcpClient())
        {
            var server = "smtp.live.com";
            var port = 25;
            client.Connect(server, port);
            using (var stream = client.GetStream())
            using (var sslStream = new SslStream(stream))
            {
                // Getting an IOException here
                sslStream.AuthenticateAsClient(server);
                using (var writer = new StreamWriter(sslStream))
                using (var reader = new StreamReader(sslStream))
                {
                    writer.WriteLine("EHLO " + server);
                    writer.Flush();
                    Console.WriteLine(reader.ReadLine());
                }
            }
        }
        Console.WriteLine("Press Enter to exit...");
        Console.ReadLine();
    }
}

Я попытался указать SslProtocol в AuthenticateAsClient.Ни Tls, ни Ssl3 не сработали.

Также попытался предоставить обратный вызов для RemoteCertificateValidation, который всегда возвращал true только в случае, если сертификат сервера был недействительным.Это тоже не сработало.

ПРИМЕЧАНИЕ: Пожалуйста, не предлагайте мне использовать SmtpClient;Мне нужно больше контроля, чем он обеспечивает.

Ответы [ 2 ]

12 голосов
/ 08 июня 2011

Спасибо, что поставили меня на правильный путь.Для серверов smtp.live.com требуется следующая последовательность событий:

  1. Соединение
  2. HELO - не будет принимать STARTTLS, пока не будет отправлено
  3. STARTTLS -очевидно, это настраивает сервер на прием зашифрованного соединения
  4. SslStream.AuthenticateAsClient () - это, похоже, позволяет инфраструктуре C # и SMTP-серверу прийти к «пониманию»:)
  5. Теперь, когдау нас есть зашифрованное соединение, обычные команды SMTP работают

В любом случае, этот код работает как для smtp.live.com, так и для smtp.gmail.com через порт 587:

class Program
{
    static void Main(string[] args)
    {
        const string server = "smtp.live.com";
        const int port = 587;
        using (var client = new TcpClient(server, port))
        {
            using (var stream = client.GetStream())
            using (var clearTextReader = new StreamReader(stream))
            using (var clearTextWriter = new StreamWriter(stream) { AutoFlush = true })
            using (var sslStream = new SslStream(stream))
            {
                var connectResponse = clearTextReader.ReadLine();
                if (!connectResponse.StartsWith("220"))
                    throw new InvalidOperationException("SMTP Server did not respond to connection request");

                clearTextWriter.WriteLine("HELO");
                var helloResponse = clearTextReader.ReadLine();
                if (!helloResponse.StartsWith("250"))
                    throw new InvalidOperationException("SMTP Server did not respond to HELO request");

                clearTextWriter.WriteLine("STARTTLS");
                var startTlsResponse = clearTextReader.ReadLine();
                if (!startTlsResponse.StartsWith("220"))
                    throw new InvalidOperationException("SMTP Server did not respond to STARTTLS request");

                sslStream.AuthenticateAsClient(server);

                using (var reader = new StreamReader(sslStream))
                using (var writer = new StreamWriter(sslStream) { AutoFlush = true })
                {
                    writer.WriteLine("EHLO " + server);
                    Console.WriteLine(reader.ReadLine());
                }
            }
        }
        Console.WriteLine("Press Enter to exit...");
        Console.ReadLine();
    }
}
2 голосов
/ 07 июня 2011

Если вы хотите использовать ssl в соединении. Вы должны использовать порт 465 для ssl или 587 для tls.

Совет: попробуйте сначала без ssl, и добавьте его после того, как все заработает.

Ссылка: http://www.checktls.com/tests.html для просмотра некоторых примеров starttls.

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