前へ << 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 までお願いします。