2011-12-04 7 views
17

.NETフレームワークには、電子メールサーバーから電子メールを取得するためのクラスTcpClientがあります。 TcpClientクラスには、最大2つのパラメータを取るサーバーに接続する4つのコンストラクターがあります。 SSLを使用していないサーバーでうまく動作します。しかし、Gmailや他の多くの電子メールプロバイダは、IMAPにSSLを使用しています。TcpClientクラスでSSLを使用する方法

私は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クラスを使用して電子メールを取得するにはどうすればよいですか?

答えて

32

TcpClientと一緒にSslStreamを使用し、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(); 

EDIT

上記のコードは、単にGmailにSSLおよび出力テストメッセージの内容を介して接続します。コードのすべての重複することなく、

明らか
 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)); 

:)

+0

ありがとうございます、あなたの答えです。しかし、ユーザーのログインが私の主な問題です。 –

+0

@MdKamruzzamanPallob:私のアップデート – codingbadger

+0

あなたの答えは非常にありがとう。私は素晴らしい作品です。ポッププロトコルを使ってメールにアクセスしています。しかし、私はimapプロトコルを使って電子メールにアクセスしたい。メールサーバーの名前とポート番号を "imap.gmail.com"と "993"に変更しましたが、動作しません。どのようにそれを行うことができますか? –

2

TcpClientによって提供されるNetworkStreamSslStreamでラップすることができます。これにより、SSLと証明書の必要な処理が提供されます。

証明書検証コールバックを実行するには、ハンドラコードを挿入する必要があります。 ServicePointManager.ServerCertificateValidationCallbackまで。

2

、具体的に上記の最良の応答を調整するには:Gmailアカウントにログインして、問題にするには、あなたがの線に沿って何かをする必要がありますコマンド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); 
関連する問題