SMTPサーバ(メール送信サーバ)との通信 (TCP利用)

Simple Mail Transfer Protocolは、 インターネットで電子メールを転送するプロトコルです。
以下ではtelnetコマンドで、SMTPサーバに接続して、メールを送信する実験をしています。

telnetコマンドは、サーバマシンを遠隔操作(Remote Control)するコマンドですが、 実質的には、キー入力した文字列をサーバへ送信し、受信した文字列を表示しているだけです。
このtelnetコマンドの送受信の機能を利用して、MTA(Message Transfer Agent)と呼ばれるソフトの代わりに メール配信プログラム(SMTPサーバ)へ接続して、やり取りをしている例です。 ウェルノンポートは25番で、mail.scc01の名前のサーバに接続する部分から始まっています。 (が入力です。)

telnet mail.scc01 25
220 SMPTサーバドメイン名表示部 ESMTP Sendmail 8.12.6/8.12.6; Tue, 18 May 2004 09:51:33 +0900
HELO xx.xx.xx.xx
250 SMPTサーバドメイン名表示部 Hello pc-4-193 [192.168.4.193], pleased to meet you
MAIL FROM:<送信者のメールアドレス表示部>
250 2.1.0 <送信者のメールアドレス表示部>... Sender ok
RCPT TO:<宛先メールアドレス入力部>
250 2.1.5 <宛先メールアドレス表示部>... Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
Subject:This is Test Mail

How are you? I am fine.
Well, let's see it again.
.250 2.0.0 i4I0pXSw023467 Message accepted for delivery
QUIT
221 2.0.0 SMPTサーバドメイン名表示部 closing connection
SMTP3サーバに送る代表的コマンドを示します。
コマンド 意味
HELO(EHLO) domain あいさつ(接続の確立)
MAIL FROM:<My Mail Address> 送り手のメールアドレス設定
RCPT TO:<Mail Address> 宛て先のメールアドレス設定(RCPTはrecipient:受領者の略です。)
DATA メールデータの設定 『.』だけの行を送るまでの範囲
QUIT 終了コマンド
RSET 処理の中
SEND FROM:<My Mail Address>発信者の指定
NOOPダミーコマンド

この応答は、始めが番号となるメッセージです。
この番号が200番や300番台であれば、正常応答メッセージ、 400や500番台であれば、エラー応答を意味します。

上記の少し薄い黒のDATAコマンドで送信される情報メール本体のメッセージで、 それ以外の情報は「エンベロープ」と呼ばれます。
エンベロープ(envelope)は、直訳の通りでメール送信に必要な情報を書く入れ物の封筒を意味するものである。

そして、DATAコマンドで送信されるメール本体のメッセージですが、この部分はヘッダとボディに分かれます。
この考え方はHTTPのはヘッダとボディに似て、ヘッダは「ヘッダ名: ヘッダ値 改行」の情報を複数かくことができます。
上記例で1行しかありませんが、「Subject:This is Test Mail」がヘッドの部分で、 これはメールの件名を意味します。ヘッダに書く主要なものを以下に示します。
ヘッダ名ヘッダ値の概要
From メール送信者の氏名とアドレス
To あて先氏名とアドレス
Subject メールの件名
Reply-To メールの返信(Fromの値と違う場合に記す)
CC カーボンコピー。同一メールを複数へ送信する場合のあて先群を記述(送信者の全てに送られるので受信側で見える情報になる。)
Bcc ブラインドカーボンコピー。同一メールを複数へ送信する場合のあて先群を記述(受信側で見えない情報で、この情報の送信はしない。)
Date メール作成日時
MIME-version 送信で使うMIMEのバージョン
Content-type ボディのメディアタイプ「Content-Type: タイプサブタイプ[; charset=文字コード 等のパラメータ]」でタイプは (text、application、image、audio、video、model、message、multipart)
Content-Transfer-Encoding ボディのエンコード情報
Message-ID MUAやMTAが生成するユニークな値
X-Mailer 使ったいるMUAの名称
Return-Path メールを送信した後、その送信先のメールアドレスが使われていなかったり存在しない場合、メールの受信サーバで自動的に送信者へ不具合を通知するための宛先。
X-Original-To 受信したメールサーバで別のメールアドレスに転送している場合などで、送信者が実際に指定した宛先がここに記録されて付加される。
Delivered-To 受信したメールサーバで別のメールアドレスに転送している場合などで、その別のメールアドレスがここに記録されて付加される。
Received 経由したメールサーバの数だけ Received が記録される。
この列挙では、基本的に下から順に経由したサーバが記録されている。
つまりヘッダ一番下の Received が送信元で、一番上の Received が自分が利用しているメールサーバになる。 そのイメージは次の通り
Received: from ○ (○[○])by ○ with SMTP ○ for <○>: ○
Received: from 「送信したパソコン名またはホスト名」 (「右記のIPアドレスのホスト名[送信したコンピュータのIPアドレス]」)
by 「受け取ったサーバ名」 with SMTPなどの転送方法 id 「転送時のID番号」
for <「宛先のメールアドレス」>; 「処理時刻」
なお、ヘッダーは無くても送信できます。またFromやToの値は、エンブローブのMAIL FROM,RCPT TOに一致させなければならない訳でははない。
封筒のあて先と内部便箋のあて先が違っても構わないと同じで、実際の送信先はエンブローブの情報で決定されます。

SMTPは、インターネット黎明期から存在するプロトコルで、 ASCIIコードと呼ばれる7ビットしか使えません。
対して、Windows などで使われる日本語のキャラクタセットはShift_JISです。
Shift_JISは、日本語などの2バイト文字とアルファベットの7bit文字を同時に扱う符号化方法の一つで、 を8bitまたは16ビットの文字として扱います。
よって7ビットしか扱えないSMTPでは、単純に使えません。
そこで、日本語のメールを送る場合は7bit×7bit(14bit)で符号化するJISコードが使われます。
但し、基本はASCIIコードと呼ばれる7ビットですから、 日本語の部分で7bitが2つ並ぶ状態に変わったこと知らせる方法が必要になります。
それには、エスケースシーケンスと呼ばれる 複数の文字を使います。
具体的には、日本語の7bitが2つ並ぶ状態の直前に、それの開始を意味する ESC $ B の3文字を使います。
対して、日本語の7bitが2つ並ぶ状態が終わってASCIIの7ビットに移行する直前に、ESC ( B の3文字をを使います。
例えば、「testですか?」の文字列は、「testESC $ B$G$9$+ESC ( B?」となります。
このキャラクタセット名は、ISO-2022-JPです。

このようにメールで日本語などを使えるように拡張した規格は、MIME(マイム:Multipurpose Internet Mail Extensions)と呼ばれます。
この規則を使うことで、画像などのバイナリ情報も送ることがきます。
例えば次のようなヘッダで、データのさまざまな符号化方法を指定できます。
Content-Transfer-Encoding: base64
base64は、バイナリデータをASCII文字で効率よく転送するために作られた符号化方法で、 6bitごとに符号化する仕様のものです。

なお、SMTP関連のRFC (IETF:Internet Engineering Task Force)を以下に示します。
RFC5321 Simple Mail Transfer Protocol
RFC2554 SMTP Service Extension for Authentication
RFC1869 SMTP Service Extensions (ESMTP)
RFC1891 SMTP Service Extension for Delivery Status Notifications (DSN)