如何在TcpClient类中使用SSL

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

我可以连接gmail服务器但无法使用email_id和密码进行身份validation。 我的validation用户代码是

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

但是这段代码无法登录。

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

您必须使用SslStream和TcpClient,然后使用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("") != -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)); 

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

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

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

要专门针对IMAP和IMAP身份validation问题定制最佳响应,您需要稍微修改代码以使用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);