Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用TcpClient类连接到smtp.live.com_C#_.net_Smtp - Fatal编程技术网

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

C# 使用TcpClient类连接到smtp.live.com,c#,.net,smtp,C#,.net,Smtp,我正在尝试使用TcpClient类连接到smtp.live.com。这里有一个连接Gmail的好例子: 不幸的是,当使用smtp.live.com更新此文件时,我在调用AuthenticateTasClient方法时收到“IOException:由于意外的数据包格式,握手失败” 我怎样才能解决这个问题 class Program { static void Main(string[] args) { using (var client = new TcpClien

我正在尝试使用TcpClient类连接到smtp.live.com。这里有一个连接Gmail的好例子:

不幸的是,当使用smtp.live.com更新此文件时,我在调用AuthenticateTasClient方法时收到“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();
    }
}
我尝试在客户端中指定SslProtocol。Tls和Ssl3都不起作用

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


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

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

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


链接:查看一些starttls示例。

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

  • 连接
  • HELO-在发送之前不会接受STARTTLS
  • STARTTLS-显然,这会设置服务器以接受加密连接
  • SslStream.authenticatesClient()-这似乎让C#框架和SMTP服务器达成了“谅解”:
  • 现在我们有了一个加密的连接,通常的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();
        }
    }
    

    或者通过检查smtp服务器是否支持StartTLS来协商TLS。你完全正确…我尝试了465和587。不行。@nos-谢谢你的提示。我想我找到了解决方法。你需要什么样的控制,而
    SmtpClient
    不提供?我正在创建一个SMTP代理,它将支持来自我们内部使用的一些不支持TLS/SSL的程序的未加密连接。SMTP代理服务器将接受来自这些程序的连接,并将信息转发到需要TLS/SSL的SMTP.live.com服务器。为什么不能使用SmtpClient进行出站连接?在我看来,只有代理中的装入连接需要自定义。@jgauffin-如果我使用SmtpClient,我需要完全接收和删除电子邮件。这可能包括多个收件人、多个CCs、多个附件等。只是工作量太多了。@eFloh-谢谢提醒。所以不让我马上这么做…不得不等24小时左右。我用一个简单的on-CodePlex创建了一个项目。希望它能帮助其他人摆脱这一困境。任何不使用SSL的示例,用于连接到intranet中的Exchange server?发送
    EHLO
    而不是
    HELO
    通常会得到多行响应,显示服务器支持的所有命令,每行从
    250
    开始。如果要使用
    EHLO
    ,则需要循环调用
    clearTextReader.ReadLine()
    ,直到响应的最后一行以
    250开头(包括响应代码后的空格)。包含更多行的SMTP响应在响应中以
    250-
    开头,而最后一行以
    250
    开头(包括空格)。