| 前へ << POP3 クライアントを作ってみよう(1) | POP3 クライアントを作ってみよう(3) >> 次へ |
このプログラムは POP3 サーバに接続し、もしメールがあればそれを表示します。 メールが届いてなければ何も行いません。
1: #!/usr/local/bin/perl -w
2:
3: # $Id: pop3-client.pl,v 1.2 2002/02/05 17:53:10 68user Exp $
4:
5: # POP3サーバ名、ユーザ名、パスワード
6: $connect_host = 'pop3.foo.bar.com';
7: $username = 'USERNAME';
8: $passwd = 'PASSWORD';
9:
10: use Socket; # Socket モジュールを使う
11:
12: # プロトコルは POP3 を使う
13: $port = getservbyname('pop3', 'tcp') || 110;
14:
15: # ホスト名を、IPアドレスの構造体に変換
16: $iaddr = inet_aton($connect_host)
17: || die "$connect_hostは存在しないホストです。\n";
18:
19: # port と IP アドレスをまとめて構造体に変換
20: $sock_addr = pack_sockaddr_in($port, $iaddr);
21:
22: # ソケット生成
23: socket(SOCKET, PF_INET, SOCK_STREAM, 0)
24: || die "ソケットを生成できません。\n";
25:
26: connect(SOCKET, $sock_addr)
27: || die "$connect_host のポート $port に接続できません。\n";
28:
29: # ファイルハンドルSOCKETをバッファリングしない
30: select(SOCKET); $|=1; select(STDOUT);
31:
32:
33: # POP3サーバにユーザ名とパスワードを送る
34: print SOCKET "USER $username\r\n";
35: print SOCKET "PASS $passwd\r\n";
36:
37: # メールの一覧を取得
38: print SOCKET "LIST\r\n";
39:
40: while (<SOCKET>){
41: # 「.」のみの行が送られてきたらループを抜ける
42: m/^\.\r\n$/ && last;
43:
44: # 「メール番号 バイト数」という行なら
45: if ( m/^(\d+) (\d+)\r\n$/ ){
46: $num=$1;
47: $size=$2;
48: # メール番号を @mails に push
49: push(@mails, $num);
50: }
51: }
52:
53: # 各メールについて
54: foreach ( @mails ){
55: # メールの内容を送信するようリクエストを送る
56: print SOCKET "RETR $_\r\n";
57:
58: while (<SOCKET>){
59: # 「.」のみの行が送られてきたらメールの終り。
60: m/^\.\r\n$/ && last;
61:
62: print $_;
63: }
64: }
65: # サーバとの接続を切る
66: print SOCKET "QUIT\r\n";
$connect_host = 'pop3.foo.bar.com';
$username = 'USERNAME';
$passwd = 'PASSWORD';
use Socket;
$port = getservbyname('pop3', 'tcp') || 110;
$iaddr = inet_aton($connect_host)
|| die "$connect_hostは存在しないホストです。\n";
$sock_addr = sockaddr_in($port, $iaddr);
socket(SOCKET, PF_INET, SOCK_STREAM, 0)
|| die "ソケットを生成できません。\n";
connect(SOCKET, $sock_addr)
|| die "$connect_host のポート $port に接続できません。\n";
select(SOCKET); $|=1; select(STDOUT);
しかも最初の3行はサーバ名、ユーザ名、パスワードを変数に代入している
だけなので、実質1行しか違わないことになります。
HTTP クライアントでは
$port = getservbyname('http', 'tcp');
だったのが、POP3 クライアントでは
$port = getservbyname('pop3', 'tcp') || 110;
となっただけですね。一見、
$port = getservbyname('pop3', 'tcp');
と書いてもいいように思えますが、/etc/services の書き方が
OS によって異なるようで、FreeBSD の /etc/services は
pop3 110/tcpと書いてありますが、Linux や Solaris の /etc/services には
pop-3 110/tcpとなっているようです。ですから、getservbyname('pop3', 'tcp') が 失敗したときには、ポート 110 を使うようにします。
34: print SOCKET "USER $username\r\n"; 35: print SOCKET "PASS $passwd\r\n";POP3 サーバにユーザ名とパスワードを送ります。当然ですが、 ここで間違ったパスワードを送ってしまうと、メールの受信はできません。
37: # メールの一覧を取得
38: print SOCKET "LIST\r\n";
39:
40: while (<SOCKET>){
41: # 「.」のみの行が送られてきたらループを抜ける
42: m/^\.\r\n$/ && last;
43:
44: # 「メール番号 バイト数」という行なら
45: if ( m/^(\d+) (\d+)\r\n$/ ){
46: $num=$1;
47: $size=$2;
48: # メール番号を @mails に push
49: push(@mails, $num);
50: }
51: }
まず POP3 サーバに LIST コマンドを送ります。すると
+OK 6 messages (10211 octets) 1 1518 2 1612 3 1636 (中略) .という返事が返ってくるので、行頭の番号を配列 @mails に格納していきます。 LIST コマンドの応答は、「.」のみの行で終わるので、正規表現「^\.\r\n」 にマッチしたとき while ループを抜けます。
53: # 各メールについて
54: foreach ( @mails ){
55: # メールの内容を送信するようリクエストを送る
56: print SOCKET "RETR $_\r\n";
57:
58: while (<SOCKET>){
59: # 「.」のみの行が送られてきたらメールの終り。
60: m/^\.\r\n$/ && last;
61:
62: print $_;
63: }
64: }
配列 @mails には、メッセージ番号が入っているので、各番号について
RETR コマンドを POP3 サーバに送ります。そしてサーバから返ってくる
メールの内容を受け取り表示します。
こちらも同様に「.」のみの行を受け取るとループを抜けます。
| 前へ << POP3 クライアントを作ってみよう(1) | POP3 クライアントを作ってみよう(3) >> 次へ |
ご意見・ご指摘は Twitter: @68user までお願いします。