C++ Builder CE ネットワークプログラミング

SMTPプロトコルでメールを送信してみよう #1 シンプルなテキストメールの場合

前記事でSMTPのさわりだけ紹介しましたが、きちんとSMTP(Simple Mail Transfer Protocol)でメールを送るので、Indyのコンポーネントを使います。ご存じだと思いますが、なんらかの端末からメールを特定のメールアドレスに送ろうとしたときに、そのメールが配送される仕組みは、

こうは行きません。メールが配送される仕組みは”いつもの”クライアント・サーバモデルによるのですが、メール配送の場合は、SMTPサーバつまりSMTPD(DはdaemonのD)が関わります。ついでですが、なんとかかんとかdと言ったらDaemon君です。滅多に出てこないので、一応紹介しておきましょうかね。

Daemon君はバックグラウンドで走っているプロセスで、ネットワーク越しのパケット等で何か帰着があれば、それに応じて”何か”を手品のように出す仕事をしています。さてsmtpdの話に戻りますが、実際は、

こんな風になっていて、クライアントAとかBとかは、目の前のPCあるいはiPhoneあるいはiPadです。もちろんAndroid端末でも同じです。上図の二つのSMTPサーバーは、メンテナンス等で止められない限り、24時間毎日稼働しています。POPというのもプロトコルで、Post Office Protocolの略称です。こちらは自分用のメールサーバーから自分に届いているメールを手元の端末(PCやiPhone)で読み出すためのプロトコルです。今回は、SMTPを使って、クライアントAがクライアントA側のメールサーバーにSMTPでメールを送る(お願いする)部分をプログラムしてみます。さて読者はご自分のメールアドレスはお持ちでしょうか?プロバイダないしキャリアから与えられたメールアドレスがあれば、随伴するメールサーバの情報が与えられている可能性が高いです。筆者のプロバイダは某comです。(バラして何か問題あるだろうか?でもsmtpdにアタックされて、筆者のアカウントがBANされるのは困るのでで、一応隠蔽します。)で、WindowsのメールクライアントたとえばBecky!(!が付くのが正式 笑)での設定は、

です。例によってバレてまずい部分には墨を塗りました。今回は、SMTPサーバのホスト名が重要で、後はSMTPSを使うというので、ポート番号も調べておきましょう。”詳細”のタブですね、

したがってポートは465ですね。SMTP認証は”PLAIN”(マル秘)です。これで日常的にこのメールアドレスは使えています。SSL/TLS関連はエラーが出たらいじりますかね。必要な情報は集まりました。

IDEから、新規VCLプロジェクトを開始します。

フォームには、TMemoTButtonを各1個置いて、他にIndy関係ではTIdSMTP,TIdSSLIOHandlerSocketOpenSSL, TIdMessage,TIdLogDebug,TIdUserPassProvider,
TIdSASLPlain
を各1個置きます。TIdなんとか類はフォーム上の場所は問いません。この時点で、

こんな風に見えていれば大丈夫です。ごちゃごちゃですね。Indyのコンポーネントは、モジュール毎に役割分担がきれいにされているのでこうなります。あー、コンポーネント間のプロパティーのリンクも書かねばならないですね。まずIdSMTP1のプロパティーは、

次に、

なかなか上手く墨が塗れませんね。IdSASLPlain1は認証のメカニズムを担当してます。認証の際のユーザーネームと具体的なパスワードは、下側のIdUserPassProvider1が供給します。

Unit1.cppは、

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{

String title = "タイトルだけど";
String body = Memo1->Lines->Text;

IdMessage1->From->Name = "Your name";
IdMessage1->From->Address = "you@somewhere.com";


TIdEMailAddressItem* to = IdMessage1->Recipients->Add();
to->Name = "To name";
to->Address = "someone@gmail.com";


IdMessage1->ContentType = "text/plain";
IdMessage1->CharSet  = "ISO-2022-JP";
IdMessage1->ContentTransferEncoding = "7bit";

UTF8String utf8Text;
char text[200];

IdMessage1->Subject = title;

IdMessage1->Body->Text = body;

IdSMTP1->Connect(); 
IdSMTP1->Send(IdMessage1);
IdSMTP1->Disconnect();
ShowMessage("mail sent");

}
//---------------------------------------------------------------------------

buildしてから実行し、Memo1に何か日本語を書いてから、

Sendをクリックすると、

こうなって、メール送信完了です。debug情報は、

smtp-auth部分。

というように、smtpのセッションの情報のやり取りがわかります。エラーが出れば、どこで出たかが一目でわかります。前半がsmtp-authで、後半が具体的なメールの送信の最初

届いたメールは、下記のようになりサブジェクトも本文もいわゆる文字化けはしていません。

これで普通のテキストだけのメールの送信はオッケーですが、メーラーとか接続設定で文字化けしないという保証はできませんので具体的に試してなにかあれば試行錯誤することになります。

コメント