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

发布于 2024-11-14 05:28:13 字数 1415 浏览 1 评论 0原文

我正在尝试使用 TcpClient 类连接到 smtp.live.com。这里有一个连接 Gmail 的精彩示例:Testing SMTP server is running via 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();
    }
}

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

还尝试为 RemoteCertificateValidation 提供回调,该回调始终返回 true,以防服务器证书无效。那也没用。

注意:请不要建议我使用SmtpClient;我需要比它提供的更多的控制。

I'm trying to connect to smtp.live.com using the TcpClient class. There is a wonderful example of connecting to Gmail here: Testing SMTP server is running via C#

Unfortunately, when updating this to work with smtp.live.com, I'm getting an "IOException: The handshake failed due to an unexpected packet format" when the AuthenticateAsClient method is called.

How can I work around this?

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();
    }
}

I tried specifying the SslProtocol in AuthenticateAsClient. Neither Tls or Ssl3 worked.

Also tried providing a callback for RemoteCertificateValidation that alway returned true just in case the server cert was invalid. That didn't work either.

NOTE: Please do not suggest that I use SmtpClient; I need more control than it provides.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

自我难过 2024-11-21 05:28:13

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

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

无论如何,这段代码适用于 smtp.live.com 和 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();
    }
}

Thanks to nos for putting me on the right track. The smtp.live.com servers require the following sequence of events:

  1. Connect
  2. HELO - will not accept the STARTTLS until this has been sent
  3. STARTTLS - apparently this sets up the server to accept an encrypted connection
  4. SslStream.AuthenticateAsClient() - this seems to let the C# framework and the SMTP server come to an "understanding" :)
  5. Now that we have an encrypted connection, the usual SMTP commands work

Anyway, this code works for both smtp.live.com AND smtp.gmail.com on port 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();
    }
}
预谋 2024-11-21 05:28:13

如果您想在连接上使用 ssl。您应该使用端口 465 进行 ssl 或使用 587 进行 tls。

提示:首先尝试不使用 ssl,然后在一切正常后添加它。

链接:http://www.checktls.com/tests.html 查看一些 starttls 示例。

If you want to use ssl on the connection. You should use port 465 for ssl or 587 for tls.

Tip: Try it first without ssl, and add it after you've got things working.

Link: http://www.checktls.com/tests.html to see some starttls examples.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文