使用TcpClient类连接到smtp.live.com

Dou*_*ter 5 .net c# smtp

我正在尝试使用TcpClient类连接到smtp.live.com.这里有一个很好的连接到Gmail的例子:测试SMTP服务器是通过C#运行的

不幸的是,当更新它以使用smtp.live.com时,我在调用AuthenticateAsClient方法时收到"IOException:由于意外的数据包格式导致握手失败".

我该如何解决这个问题?

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试在AuthenticateAsClient中指定SslProtocol.Tls或Ssl3都不起作用.

还尝试提供RemoteCertificateValidation的回调,以便在服务器证书无效的情况下返回true.那也行不通.

注意:请不要建议我使用SmtpClient; 我需要更多的控制权.

Dou*_*ter 12

感谢nos让我走上正轨.smtp.live.com服务器需要以下事件序列:

  1. HELO - 在发送之前不接受STARTTLS
  2. STARTTLS - 显然这会将服务器设置为接受加密连接
  3. SslStream.AuthenticateAsClient() - 这似乎让C#框架和SMTP服务器达成"理解":)
  4. 现在我们有了加密连接,通常的SMTP命令可以正常工作

无论如何,此代码适用于端口587上的smtp.live.com和smtp.gmail.com:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)