POP3の概要
この節では、POP3について概要を説明します。
POP3とは
POP3(Post Office Protocol version 3)は、いわゆる「メールを受信する」ためのプロトコルです。
POP3のおおまかな特徴は以下の2つです。
- クライアント・サーバ形式
- テキストベースのプロトコル
まず、POP3はクライアント・サーバ形式です。つまり、ネットワーク経由で通信するプログラム同士の立場が非対称で、「相手に使われる」プログラム(=サーバ)と「相手を使う」プログラム(=クライアント)に分かれます。POP3ではメールを持っているほうがサーバで、メールを受信する側がクライアントです。POP3サーバの例としてはqpopper、POP3クライアントの例としてはMicrosoft OfficeのOutlookなどが挙げられます。
次に、POP3はテキストベースのプロトコルです。つまり、ASCIIのプレーンテキストでサーバとクライアントが通信します。この点はウェブの基本プロトコルであるHTTPや、メール送信用プロトコルであるSMTPと似ています。
POP3セッションの例
百聞は一見に如かずです。実際にPOPdを動かして、POP3の中身を見てみましょう。コマンドラインで次のように入力するとPOPdをデバッグモード、かつinetdモードで実行できます。このモードでは、端末からPOPdと直接やりとりできます。
$ ruby -d popd.rb --inetd Exception `Errno::ENOTSOCK' at popd.rb:92 - Socket operationon non-socket - getpeername(2) +OK popd <1162129240.4663.154af7768c@pop.example.com>
「Exception……」の行はrubyが(正しく捕捉された)例外の情報を表示しているだけなので、無視してください。次の「+OK……」と表示されている行からが、POPdの出力です。
ここでキーボードからPOP3のコマンドを打ち込んでみましょう。最初にAPOPコマンドで認証を行います。
C: APOP taro xxxx S: +OK
「C:」と「S:」は説明のために付けているだけで、実際には表示されません。頭に「C:」と付いている行はこちら(クライアント)からの入力、「S:」と付いている行がPOPd(サーバ)からの出力を表しています。
さて、APOPコマンドの引数は2つです。1つめの引数「taro」がユーザー名で、2つめの引数「xxxx」は実装の節で詳述する「ダイジェスト」です。サーバが「+OK」と返してきたら問題なく認証されたということを示しています。
認証が済んだらメールボックスにアクセスできます。まずSTATコマンドでメール数などを調べてみましょう。
C: STAT S: +OK 3 10867
うまくいきました。この返答は、「メールボックスにはメールが3通あり、そのバイト数の合計は10867バイトである」という意味です。
ところで、さきほどからサーバが返してきている「+OK」は、「処理が問題なくうまくいった」という意味です。何か問題が起きた場合は「-ERR」が返ってきます。例えば次はPOP3には存在しないコマンドを入力してみましょう。
C: NO_SUCH_COMMAND S: -ERR unknown command
このように、POP3にはないコマンドを送ったらサーバから「-ERR」が返ってきました。
次はLISTコマンドを使ってメールをリストアップしてみます。
C: LIST S: +OK S: 1 1370 S: 2 4901 S: 3 4596 S: .
LISTコマンドへの返答は複数行です。POP3で複数行の応答があるときは、「.」だけの行で終わりを示します。
この返答の意味は、「メール番号1のメールはサイズが1370バイト、メール番号2のメールはサイズが4901バイト、メール番号3のメールはサイズが4596バイト」です。通常、メール番号は1から通し番号が振られています。
今度は、RETRコマンドでメールを取得してみましょう。RETRはretrieve(受け取る)の略です。
C: RETR 1
S: +OK 1370 octets
S: Return-path: <xxxxxxxxx@example.com>
S: Envelope-to: taro@example.com
S: Delivery-date: Sun, 29 Oct 2006 00:49:01 +0900
S: Received: from [xxx.xxx.xxx.xxx]
S: by pop.example.com with smtp
S: id 1GdqQe-0007Mo-Ug
S: for taro@example.com; Sun, 29 Oct 2006 00:49:01 +0900
(メールの内容は中略)
S: この行はメールの本体……
S: この行もメールの本体……
S: .
RETRコマンドの引数は、取得したいメールのメール番号です。この例では1番のメールを取得しようとしています。サーバはそれに応答して、まず2行目の「+OK 1370 octets」で「次の行からメールを送る」と言っています。次の行からはメールの内容が続き、最後に「.」だけの行でメールの終わりを示します。
なお、この仕組みだともともと「.」だけの行を含むメールを受信するときに問題が起きそうな気もしますが、POP3ではそのための対策も用意されています。この対策についてはRETRコマンドの実装をするときに述べます。
メールを取得できたら、DELEコマンドでメールを削除します。
C: DELE 1 S: +OK
これでメール番号1番のメールが削除できました。最後に、QUITコマンドでPOP3セッションを終了します。
C: QUIT S: +OK
最後の「+OK」が送られてくると同時にTCP接続がサーバ側から切断されて、コマンドプロンプトに戻ってきます。
次の節からは実際のコードを見ていくことにしましょう。

on non-socket - getpeername(2)
+OK popd <1162129240.4663.154af7768c@pop.example.com>