読者です 読者をやめる 読者になる 読者になる

メール送信のやり方

C# .NET

SMTPでメール送信する例が下記にあります。

http://dobon.net/vb/dotnet/internet/smtpmail.html

// using System.Net.Mail;しておく
SmtpClient sc = new SmtpClient();
sc.Host = "smtp.mail.yahoo.co.jp";
string subject = "メールの件名";
string from = "hogehoge@yahoo.co.jp";
string to = "fugafuga@gmail.com";
sc.Send(from, to, subject, "メールの本文");

んでもって、Yahoo!メールのPOPアクセスのSMTPサーバはPOP before SMTPなので、いきなりSMTPで送信しようとすると、

smtp.mail.yahoo.co.jp closing transmission channel. You must be pop-authenticated before you can use this smtp server, and you must use your yahoo mail address for the Sender/From field.

と起こられて、System.Net.Mail.SmtpExceptionになります。

では、POP3でメールを読む方法はCLRに用意してあるかというと、C#でPOP3メール受信 - 果てしないたわごとによればないらしく自分で作るしかないらしい。

POP before SMTPをクリアすれば良い→単にログインできれば良いなので、下記のソースコードを流用してログイン・ログアウトするメソッドを追加しました。

http://dobon.net/vb/dotnet/internet/receivepop3mail.html

using System.Net.Sockets;

public class Pop3Mail
{
    TcpClient client;
    NetworkStream stream;

    public void login(string hostName,
        int portNumber,
        string userId,
        string passWord)
    {
        //TcpClientの作成
        this.client = new TcpClient();
        //タイムアウトの設定
        this.client.ReceiveTimeout = 10000;
        this.client.SendTimeout = 10000;

        string msg = "";

        try
        {
            //サーバーに接続
            client.Connect(hostName, portNumber);
            //ストリームの取得
            this.stream = client.GetStream();
            //受信
            msg = ReceiveData(stream);

            //USERの送信
            SendData(this.stream, "USER " + userId + "\r\n");
            //受信
            msg = ReceiveData(this.stream);

            //PASSの送信
            SendData(this.stream, "PASS " + passWord + "\r\n");
            //受信
            msg = ReceiveData(this.stream);
        }
        catch
        {
            throw;
        }
    }

    public void logout()
    {
        string msg = "";
        try
        {
            //QUITの送信
            SendData(this.stream, "QUIT\r\n");
            //受信
            msg = ReceiveData(this.stream);
        }
        catch
        {
            throw;
        }
        finally
        {
            //切断
            this.client.Close();
        }
    }

    //データを受信する
    private string ReceiveData(
        NetworkStream stream,
        bool multiLines,
        int bufferSize,
        Encoding enc)
    {
        byte[] data = new byte[bufferSize];
        int len;
        string msg = "";
        System.IO.MemoryStream ms = new System.IO.MemoryStream();

        //すべて受信する
        //(無限ループに陥る恐れあり)
        do
        {
            //受信
            len = stream.Read(data, 0, data.Length);
            ms.Write(data, 0, len);
            //文字列に変換する
            msg = enc.GetString(ms.ToArray());
        }
        while (stream.DataAvailable ||
            ((!multiLines || msg.StartsWith("-ERR")) &&
            !msg.EndsWith("\r\n")) ||
            (multiLines && !msg.EndsWith("\r\n.\r\n")));

        ms.Close();

        //"-ERR"を受け取った時は例外をスロー
        if (msg.StartsWith("-ERR"))
            throw new ApplicationException("Received Error");

        //表示
        Console.Write("S: " + msg);

        return msg;
    }
    private string ReceiveData(NetworkStream stream,
        bool multiLines,
        int bufferSize)
    {
        return ReceiveData(stream, multiLines, bufferSize,
            Encoding.GetEncoding(50220));
    }
    private string ReceiveData(NetworkStream stream,
        bool multiLines)
    {
        return ReceiveData(stream, multiLines, 256);
    }
    private string ReceiveData(NetworkStream stream)
    {
        return ReceiveData(stream, false);
    }

    //データを送信する
    private void SendData(NetworkStream stream,
        string msg,
        Encoding enc)
    {
        //byte型配列に変換
        byte[] data = enc.GetBytes(msg);
        //送信
        stream.Write(data, 0, data.Length);

        //表示
        Console.Write("C: " + msg);
    }
    private void SendData(NetworkStream stream,
        string msg)
    {
        SendData(stream, msg, Encoding.ASCII);
    }
}