【问题标题】:How to use SSL in TcpClient class如何在 TcpClient 类中使用 SSL
【发布时间】:2012-01-12 14:02:54
【问题描述】:

在 .NET 框架中有一个类 TcpClient 用于从电子邮件服务器检索电子邮件。 TcpClient 类有 4 个构造函数来连接服务器,最多接受两个参数。它适用于那些不使用 SSL 的服务器。但是 gmail 或许多其他电子邮件提供商使用 SSL 进行 IMAP。

我可以连接 gmail 服务器,但无法使用 email_id 和密码进行身份验证。

我的验证用户代码是

public void AuthenticateUser(string username, string password)
{
    _imapSw.WriteLine("$ LOGIN " + username + " " + password);
    //_imapSw is a object of StreamWriter class
    _imapSw.Flush();
    Response();
}

但是这段代码无法登录。

那么当我必须使用 SSL 时,如何使用 TcpClient 类来检索电子邮件?

【问题讨论】:

    标签: c# .net email tcpclient


    【解决方案1】:

    您可以用SslStream 包装TcpClient 提供的NetworkStream。这将提供对 SSL 和证书的必要处理。

    您可能需要插入一些处理程序代码来执行证书验证回调,例如通过ServicePointManager.ServerCertificateValidationCallback

    【讨论】:

      【解决方案2】:

      您必须使用SslStreamTcpClient,然后使用 SslStream 而不是 TcpClient 来读取数据。

      类似的东西:

              TcpClient mail = new TcpClient();
              SslStream sslStream;
      
              mail.Connect("pop.gmail.com", 995);
              sslStream = new SslStream(mail.GetStream());
      
              sslStream.AuthenticateAsClient("pop.gmail.com");
      
              byte[] buffer = new byte[2048];
              StringBuilder messageData = new StringBuilder();
              int bytes = -1;
              do
              {
                  bytes = sslStream.Read(buffer, 0, buffer.Length);
      
                  Decoder decoder = Encoding.UTF8.GetDecoder();
                  char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
                  decoder.GetChars(buffer, 0, bytes, chars, 0);
                  messageData.Append(chars);
      
                  if (messageData.ToString().IndexOf("<EOF>") != -1)
                  {
                      break;
                  }
              } while (bytes != 0);
      
              Console.Write(messageData.ToString());
              Console.ReadKey();
      

      编辑

      上面的代码将简单地通过 SSL 连接到 Gmail 并输出测试邮件的内容。要登录 gmail 帐户并发出命令,您需要执行以下操作:

              TcpClient mail = new TcpClient();
              SslStream sslStream;
              int bytes = -1;
      
              mail.Connect("pop.gmail.com", 995);
              sslStream = new SslStream(mail.GetStream());
      
              sslStream.AuthenticateAsClient("pop.gmail.com");
      
              byte[] buffer = new byte[2048];
              // Read the stream to make sure we are connected
              bytes = sslStream.Read(buffer, 0, buffer.Length);
              Console.WriteLine(Encoding.ASCII.GetString(buffer, 0, bytes));
      
              //Send the users login details
              sslStream.Write(Encoding.ASCII.GetBytes("USER USER_EMAIL\r\n"));
              bytes = sslStream.Read(buffer, 0, buffer.Length);
              Console.WriteLine(Encoding.ASCII.GetString(buffer, 0, bytes));
      
              //Send the password                        
              sslStream.Write(Encoding.ASCII.GetBytes("PASS USER_PASSWORD\r\n"));
              bytes = sslStream.Read(buffer, 0, buffer.Length);
              Console.WriteLine(Encoding.ASCII.GetString(buffer, 0, bytes));
      
              // Get the first email 
              sslStream.Write(Encoding.ASCII.GetBytes("RETR 1\r\n"));
              bytes = sslStream.Read(buffer, 0, buffer.Length);
              Console.WriteLine(Encoding.ASCII.GetString(buffer, 0, bytes));
      

      显然,没有所有重复的代码:)

      【讨论】:

      • 谢谢您的回答。但用户登录是我的主要问题。
      • 非常感谢您的回答。我工作得很好。在某种程度上它使用 pop 协议来访问邮件。但我想使用 imap 协议访问电子邮件。我已将邮件服务器名称和端口号更改为“imap.gmail.com”和“993”,但它不起作用。怎么做?
      • 如果您是“服务器”而不是客户端,这将如何改变?我想使用 ssl 接收连接?
      • 我在循环的第二次迭代中冻结了 bytes = sslStream.Read(buffer, 0, buffer.Length) 因为 messageData.ToString() 没有
      【解决方案3】:

      要针对 IMAP 和 IMAP 身份验证问题定制上述最佳响应,您需要稍微修改代码以使用 IMAP 命令,如下所示。对于调试,您可以在分配 strOut 后设置断点以查看服务器响应。

                  pmOffice pmO = new pmOffice();
                  pmO.GetpmOffice(3, false);
      
                  TcpClient mail = new TcpClient();
                  SslStream sslStream;
                  int bytes = -1;
      
                  mail.Connect("outlook.office365.com", 993);
                  sslStream = new SslStream(mail.GetStream());
      
                  sslStream.AuthenticateAsClient("outlook.office365.com");
      
                  byte[] buffer = new byte[2048];
                  // Read the stream to make sure we are connected
                  bytes = sslStream.Read(buffer, 0, buffer.Length);
                  Console.WriteLine(Encoding.ASCII.GetString(buffer, 0, bytes));
      
                  //Send the users login details (insert your username & password in the following line
                  sslStream.Write(Encoding.ASCII.GetBytes("$ LOGIN " + pmO.mailUsername + " " + pmO.mailPassword + "\r\n"));
                  bytes = sslStream.Read(buffer, 0, buffer.Length);
                  string strOut = Encoding.ASCII.GetString(buffer, 0, bytes);
      
                  // Get the status of the inbox (# of messages)
                  sslStream.Write(Encoding.ASCII.GetBytes("$ STATUS INBOX (messages)\r\n"));
                  bytes = sslStream.Read(buffer, 0, buffer.Length);
                  strOut = Encoding.ASCII.GetString(buffer, 0, bytes);
      

      【讨论】:

      • 什么是 pmOffice?
      • pmOffice 是我创建的一个类,用于从数据库访问我的邮件设置和凭据。
      猜你喜欢
      • 2011-10-06
      • 1970-01-01
      • 2017-09-04
      • 1970-01-01
      • 2016-03-23
      • 2016-01-07
      • 2011-09-10
      • 2012-06-06
      • 2014-05-06
      相关资源
      最近更新 更多