CLX C++ Libraries
Home >> smtp

Declaration

template <class Socket>
class basic_smtp : public Socket;

typedef basic_smtp<tcp::socket> smtp;

namespace smtp_auth {
    enum {
        none     = 0x01,
        plain    = 0x02,
        login    = 0x04,
        cram_md5 = 0x08,
        best     = 0x0f
    };
}

Overview

smtp クラスは SMTP (Simple Mail Transfer Protocol) でメールを送信するためのクラスです. start() メソッドでメールサーバと接続し,login() メソッドでログイン処理を行った後, mail() メソッドで実際にメールを送信します.login() メソッドは現在のところ PLAIN, LOGIN, CRAM-MD5 方式に対応しており,どの方式を用いるかを login() メソッドの第 3 引数に指定します.

実際にメールを送信する mail() メソッドには,引数としてメールの内容を直接指定する代わりに, 関数オブジェクト(または,関数ポインタ)を指定することもできます. 引数として関数オブジェクトが指定された場合,smtp クラスはメールの内容を 受信するための入力ストリームを関数オブジェクトへ渡します.指定する関数オブジェクト, または関数ポインタには以下ような関数が定義されている必要があります.

// 関数の場合
void sendmail(std::ostream& sout);

// 関数オブジェクトの場合
class sendmail {
public:
    template <class OutputStream>
    void operator()(OutputStream& sout);
};

smtp クラスは,サーバからエラーメッセージが返された場合には smtp_error を例外として送出します. また,smtp クラスはサーバからの応答メッセージを内部に蓄積するように実装しています. responses() メソッドを呼ぶと,サーバからの応答メッセージの一覧を取得することができます.

Example

example_smtp.cpp

#include <iostream>
#include <string>
#include <sstream>
#include "clx/smtp.h"
#include "clx/date_time.h"

int main(int argc, char* argv[]) {
    if (argc < 6) {
        std::cerr << "usage " << argv[0] << " host id pass from to" << std::endl;
        std::exit(-1);
    }
    
    try {
        clx::smtp session(argv[1], 25);
        
        /*
         * 第3引数でSMTP-AUTH の方法を指定する.
         *   - clx::smtp_auth::plain
         *   - clx::smtp_auth::login
         *   - clx::smtp_auth::cram_md5
         *
         * clx::smtp_auth::none を指定すると SMTP-AUTH は行わずに EHLO パケット
         * を送信するのみ.clx::smtp_auth::best を指定すると,
         * cram_md5 -> plain -> login の順番でサーバがサポートしているかどうか
         * 調べ,最初にサポートしていた方式で認証を行う.いずれにも対応していない
         * 場合は,clx::smtp_auth::none を指定した場合と同じ.
         * 
         * 第3引数の省略時は,clx::smtp_auth::best.
         */
        session.login(argv[2], argv[3]);
        
        std::string from(argv[4]);
        std::string to(argv[5]);
        
        // create a sample message
        std::stringstream msg;
        clx::date_time now;
        msg << "Date: " << now.to_string<char>("%a, %d %b %Y %H:%M:%S +0900") << "\r\n";
        msg << "From: " << from << "\r\n";
        msg << "To: " << to << "\r\n";
        msg << "Subject: SMTP test mail\r\n";
        msg << "\r\n";
        msg << "This ia test mail for clx::smtp class.\r\n";
        msg << ".\r\n";
        session.mail(from, to, msg.str());
        session.finish();
        
        // print message log
        clx::smtp::response_array::reverse_iterator pos;
        for (pos = session.responses().rbegin();
            pos != session.responses().rend(); ++pos) {
            std::cout << pos->second << std::endl;
            std::cout << std::endl;
        }
    }
    catch (clx::smtp_error& e) {
        std::cerr << e.code() << ": " << e.what() << std::endl;
        std::exit(-1);
    }
    catch (clx::socket_error& e) {
        std::cerr << e.what() << std::endl;
        std::exit(-1);
    }
    catch (std::runtime_error& e) {
        std::cerr << e.what() << std::endl;
        std::exit(-1);
    }
    
    return 0;
}
Result
s273.xrea.com ESMTP

s273.xrea.com
AUTH LOGIN CRAM-MD5 PLAIN
AUTH=LOGIN CRAM-MD5 PLAIN
PIPELINING
8BITMIME

PDkwNjcuMTIzMDI0NDMyN0BzMjczLnhyZWEuY29tPg==

ok, go ahead (#2.0.0)

ok

ok

go ahead

ok 1230244328 qp 9069

s273.xrea.com

宛先を複数指定する場合,および mail() メソッドに関数オブジェクトを指定する場合のサンプルコードは example_smtp_list.cpp を参照して下さい.

Template Parameters

Socket
ソケットクラスを指定します.

Related Types

typedef Socket socket_type;
typedef char char_type;
typedef std::basic_string<char_type> string_type;

typedef std::pair<int, string_type> response_type;
typedef std::deque<response_type> response_array;

Construction and Member Functions

basic_smtp();
basic_smtp(const basic_smtp& cp);
explicit basic_smtp(const string_type& host, int port = 25);
explicit basic_smtp(const char_type* host, int port = 25);
virtual ~basic_smtp();

basic_smtp& start(const string_type& host, int port = 25);
basic_smtp& start(const char_type* host, int port = 25);

void finish();

basic_smtp& login(const string_type& id);
basic_smtp& login(const char_type* id);

basic_smtp& login(const string_type& id, const string_type& pass,
    int type = smtp_auth::best);
basic_smtp& login(const char_type* id, const char_type* pass,
    int type = smtp_auth::best);

start() メソッドで SMTP サーバと接続し,login() メソッドでログイン処理を行います. login() の第 3 引数として指定できる値は,smtp_auth::none, smtp_auth::plain, smtp_auth::login, smtp_auth::cram_md5, smtp_auth::best の 5 種類です.

clx::smtp_auth::none を指定すると SMTP-AUTH は行わずに EHLO パケットを送るのみで login() を終了します.smtp_auth::plain, smtp_auth::login, smtp_auth::cram_md5 を指定すると,それぞれ PLAIN, LOGIN, CRAM-MD 方式で認証を試みます. smtp_auth::best を指定すると,CRAM-MD5, PLAIN, LOGIN の順序でサーバがその認証方式を サポートしているかどうか調べ,最初に見つけた方式で認証を行います. いずれの方式にも対応していない場合は,clx::smtp_auth::none を指定した場合と同じ挙動になります.

login() メソッドの第 3 引数を省略した場合は smtp_auth::best が指定されたと見なされます.

template <class Functor>
basic_smtp& mail(const string_type& from, const string_type& to, Functor f);

basic_smtp& mail(const string_type& from, const string_type& to,
    const string_type& message);

template <class MailingList, class Functor>
basic_smtp& mail(const string_type& from, const MailingList& to, Functor f);

template <class MailingList>
basic_smtp& mail(const string_type& from, const MailingList& to,
    const string_type& message);

実際にメールを送信するときは,送信元,宛先,メールの内容を引数として指定し mail() メソッドを実行します.宛先は複数指定することもできます. 複数の宛先を指定する際には,宛先のリスト (e.g., std::vector<std::string>, std::list<std::string>, ...) を作成して第 2 引数に指定して下さい.

response_array& responses();
const response_array& responses() const;
const response_type& response(size_t index) const;

response() メソッドは,SMTP サーバからの応答メッセージの一覧を取得するためのメソッドです. それぞれの応答メッセージ (response_type) は,応答コードとメッセージのペアで構成されています. サーバからの応答メッセージはキュー (正確には std::deque) で管理しているため, 最新のメッセージが先頭に格納されています.

Related Pages

  1. CLX C++ Libraries - smtps
  2. CLX C++ Libraries - pop3
  3. CLX C++ Libraries - pop3s