ネットワークコマンド

■ PerlでPINGしてみる(Net::Ping)

◆ マシンと通信できる状態か確認

ping は、ICMP-ECHO-REQUEST という特別なパケットを送信して、その応答(ICMP-ECHO-REPLY)があるか無いかで、相手ホストと通信できる状態かどうかを調べるコマンドです。UNIX でも Windows でもサポートされています。Perl で ping を実現するには Net::Ping モジュールを使用します。

ping-icmp.pl
use Net::Ping;
$host = "www.yahoo.co.jp";
$timeout = 5; 
$ping = Net::Ping->new("icmp");
if ($ping->ping($host, $timeout)) {
    print "$host と通信できます。\n";
} else {
    print "$host 通信できません。\n";
}
$ping->close();

※ UNIX の場合、root 権限で実行してください。

◆ TCPで接続可能かどうか調べる

指定した TCP のポートに接続可能かどうかを調べることもできます。下記の例では HTTP の 80 番ポートが生きているか調べます。Windows ではアラームがサポートされていないため、動作しないようです。

ping-tcp.pl
use Net::Ping;
$host = "www.yahoo.co.jp";
$ping = Net::Ping->new("tcp", 80);
if ($ping->ping($host)) { print "通信できます。\n"; }
$ping->close();
◆ UDP-ECHO を用いた確認

"udp" を指定した場合は、UDP-ECHO の機能を用いて確認を行います。

ping-udp.pl
use Net::Ping;
$host = "www.yahoo.co.jp";
$ping = Net::Ping->new("udp");
if ($ping->ping($host)) { print "通信できます。\n"; }
$ping->close();

■ PerlでFTPしてみる(Net::FTP)

◆ 基本的な使用方法

Net::FTP モジュールを用いることで、FTP によるファイルのダウンロードが可能になります。

net-ftp.pl
use Net::FTP;

$ftpserver = "ftp.yyy.zzz";           # FTPサーバ名
$login = "tanaka";                    # ログイン名
$passwd = "hi.mi.tu";                 # パスワード
$downfile = "down.zip";               # ダウンロードファイル名
$upfile = "up.zip";                   # アップロードファイル名

$ftp = Net::FTP->new($ftpserver) || die "new";   # 初期化
$ftp->login($login, $passwd) || die "login";     # ログイン
$ftp->cwd("public_html") || die "cwd";           # フォルダ移動
$ftp->get($downfile) || die "get";               # ダウンロード
$ftp->put($upfile) || die "put";                 # アップロード
$ftp->quit() || die "quit";                      # 終了
◆ ファイルの一覧

ファイルの一覧を得るには次のようにします。dir() は配列へのリファレンスを返すので、@$ でデリファレンスしてやります。

$refOfDirList = $ftp->dir();
foreach $file (@$refOfDirList) {
    print "$file\n";
}
◆ その他の主な機能

その他、よく使用される機能として次のものがあります。

$ftp->rename($oldname, $newname);     # 名前を変更する
$ftp->delete($filename);              # ファイルを削除する
$ftp->mkdir($dirname);                # ディレクトリを作成する
$ftp->rmdir($dirname);                # ディレクトリを削除する
$ftp->binary();                       # バイナリモードにする
$ftp->ascii();                        # テキストモードにする
$ftp->site("chmod", "0755", $file);   # 属性を変更する

■ Perlでメール送信してみる(Net::SMTP)

◆ SMTPでメールを送信する

SMTP というメール送信のプロトコルを用いて、メールを送信します。

net-smtp.pl
use Net::SMTP;
use MIME::Base64;
require "jcode.pl";

$server = "mail.xxx.zzz";                    # SMTPサーバ名
$from = "tanaka\@xxx.zzz";                   # 送信元メールアドレス
$to = "suzuki\@xxx.zzz";                     # あて先メールアドレス
$subject = "これはテストメールです";         # 件名
$message = "こんにちわ\nまた会いましょう\n"; # メールの本文

# 件名の日本語をエンコードする
jcode::convert(*subject, "jis");
$subject = encode_base64($subject);
$subject =~ s/^(.*)$/=?iso-2022-jp?B?$1=?=/mg;

# 本文をJISコードに変換する
jcode::convert(*message, "jis");

# メールを送信する
$smtp = Net::SMTP->new($server) || die "smtp";
$smtp->mail($from) || die "mail";
$smtp->to($to) || die "to";
$smtp->data() || die "data";
$smtp->datasend("To: $to\n") || die "datasend";
$smtp->datasend("From: $from\n") || die "datasend";
$smtp->datasend("Subject: $subject\n") || die "datasend";
$smtp->datasend("\n") || die "datasend";
$smtp->datasend($message) || die "datasend";
$smtp->dataend() || die "dataend";
$smtp->quit() || die "quit";

メールの本文に日本語を使用する場合は、JISコードに変換する必要があります。(→「漢字コードを変換する」)

また、件名やメールアドレスのコメント部など、メールヘッダの部分に日本語を使用するには、文字列を JISコードに変換した後、さらにこれを BASE64 形式にエンコードし、その前後に "=?iso-2022-jp?B?" と "=?=" のおまじないの文字列を付加してやる必要があります。

■ Perlでメール受信してみる(Net::POP3)

◆ POP3でメールを読み出す

POP3 というメール読み出しのプロトコルを用いて、メールサーバからメールを読み出します。引数を省略するとメール番号の一覧を表示します。引数にメール番号を指定すると、そのメールを読み出して表示します。$pop->delete($num) を行わなければ、メールは読み出してもメールサーバに残ったままになります。

net-pop3.pl
use Net::POP3;
require "jcode.pl";

$server = "mail.yyy.zzz";      # メールサーバ名
$user = "tanaka";              # ユーザ名
$pass = "hi.mi.tu";            # パスワード
$kcode = "sjis";               # 表示の際の漢字コード

$pop = Net::POP3->new($server) || die "pop";
$pop->user($user) || die "user";
$pop->pass($pass) || die "pass";

if ($#ARGV == -1) {
    $refOfHash = $pop->list();
    while (($name, $value) = each(%$refOfHash)) {
        print "$name : $value bytes\n";
    }
} else {
    $refOfLines = $pop->get($ARGV[0]);
    foreach $line (@$refOfLines) {
        jcode::convert(*line, $kcode);
        print $line;
    }
}

$pop->quit();

list() はメール番号をキー、そのサイズを値としてもつハッシュへのリファレンスを、get() はメールの各行を要素とする配列へのリファレンスを返します。

■ PerlでHTTPしてみる(LWP::Simple)

◆ LWPとは

LWP は Library for WWW access in Perl の略です。HTTP を用いて WWW サーバにアクセスするためのいろいろな機能を提供しています。

◆ HTTPでウェブページを簡単に読み込む(LWP::Simple)

LWP::Simple モジュールを用いると、HTTP を用いたウェブページの取得が簡単にできてしまいます。

http-simple.pl
use LWP::Simple;
print get("http://www.yahoo.co.jp/");

getprint() は、読み込みと表示を同時に行います。戻り値として、403 などの HTTP ステータスコードを返します。

$code = getprint("http://www.yahoo.co.jp/");

getstore() は、読み込んだ内容をファイルに保存します。

$code = getstore("http://www.yahoo.co.jp/", "yahoo.htm");

mirror() は、HTTP の If-Modified-Since 機能を用いて、ローカルファイルの更新日よりも、サーバ上のファイルの更新日のほうが新しい場合のみ、内容を読み込んでローカルファイルに保存します。

$code = mirror("http://www.yahoo.co.jp/", "yahoo.htm");

head() を用いると、ウェブページに関するタイプ、サイズ、変更日付、キャッシュ有効期間、サーバ情報を読み出すことができます。

($type, $length, $mod, $expires, $server) = head("http://www.w3.org/");
print "Content-Type: $type\n";
print "Content-Length: $length\n";
print "Last-Modified: $mod\n";
print "Expires: $expires\n";
print "Server: $server\n";

■ ちょっと高度なHTTPアクセス(LWP::UserAgent)

◆ ちょっと高度なHTTPアクセス

LWP::UserAgent を用いると、少し高度な HTTP アクセスが可能になります。まずは基本パターンから。ユーザエージェントオブジェクト($ua)を作成し、要求メッセージ($req)を作成し、要求(request)を行い、応答($res)を受け取り、内容(content)を表示します。

http-ua.pl
use LWP::UserAgent;

$ua = LWP::UserAgent->new();
$req = HTTP::Request->new("GET", "http://www.yahoo.co.jp/");
$res = $ua->request($req);
print $res->content();
◆ 成功か失敗かを確認する

is_success() を用いて処理が成功したか失敗したかを確認することができます。

    :
$res = $ua->request($req);
if ($res->is_success()) { print "成功しました。\n"; }
    :
◆ 1024バイトずつ読み込む

巨大なデータを読み込む際でも、読み込みデータを 1024 バイトずつなどに分割して読み込むことができます。

    :
$res = $ua->request($req, \&callback);

sub callback {
    local($data, $res, $protocol) = @_;
    print $data;
}
◆ 応答のHTTPヘッダを読み出す

次のようにして応答の HTTP ヘッダを調べることができます。

print "Content-Length = " . $res->header("Content-Length") . "\n";
print "Content-Type = " . $res->header("Content-Type") . "\n";
print "Last-Modified = " . $res->header("Last-Modified") . "\n";
◆ フォームデータを送信する

HTTP::Request::Common を用いると、フォームデータを簡単に送信することができます。

use HTTP::Request::Common qw(POST);
use LWP::UserAgent;

$ua = LWP::UserAgent->new();
$req = POST "http://www.xxx.zzz/test/test.cgi",
            [ DATA1 => "data1", DATA2 => "日本語" ];
$res = $ua->request($req);
print $res->content();
◆ プロキシを指定する

プロキシサーバを指定するには、UserAgent オブジェクトの proxy() メソッドを用います。

    :
$ua = LWP::UserAgent->new();
$ua->proxy("http", "http://proxy.xxx.zzz:8080/");
    :
◆ BASIC認証のユーザ名とパスワードを渡す

authorization_basic() メソッドを用いてユーザ名とパスワードを指定することで、BASIC認証のページで保護されたページへアクセスすることが可能になります。

    :
$req = HTTP::Request->new("GET", "http://www.xxx.zzz/");
$req->authorization_basic("tanaka", "hi.mi.tu");
$res = $ua->request($req);
    :
◆ Cookie を扱うページに対応する

下記のように、Cookie 情報を保存するファイルを指定しておくと、要求時に Cookie 情報を送信し、応答受信時に受け取った Cookie 情報をファイルに書き込みます。

    :
$ua->cookie_jar(HTTP::Cookies->new(file => "cook.txt", autosave => 1));
    :

Copyright (C) 2002 杜甫々