.NETフレームワークには、メールサーバーからメールを取得するためのTcpClient
クラスがあります。 TcpClient
クラスには、サーバーと接続するための4つのコンストラクターがあり、最大2つのパラメーターを受け取ります。 SSLを使用しないサーバーで正常に動作します。しかし、Gmailや他の多くのメールプロバイダーはIMAPに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
クラスを使用して電子メールを取得するにはどうすればよいですか?
SslStream を TcpClient と一緒に使用してから、TcpClientではなくSslStreamを使用してデータを読み取る必要があります。
以下に沿ったもの:
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));
明らかに、コードの重複は一切ありません:)
NetworkStream
によって提供されるTcpClient
を SslStream
でラップできます。これにより、SSLと証明書の必要な処理が提供されます。
証明書検証コールバックを実行するために、ハンドラコードを挿入する必要がある場合があります。使って - ServicePointManager.ServerCertificateValidationCallback
。
上記の最良の応答を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);