コンピュータネットワーク基礎
2005.06.10

Back to index page

  1. 本日の作業内容



  2. 出席確認

    電子メールで出席確認をします.宛先など以下の情報を用いてメールを作成し, 出席申告してください.なお,キーワードは授業中に紹介します.

    提出形式

    宛先 justice@mag.shimane-u.ac.jp
    件名 AttendA_06-10_net_s0340** Aクラス
    AttendB_06-10_net_s0340** Bクラス
    本文 学生番号
    氏名
    キーワード
     
    (改行)
    (改行)
    キーワードは授業中に紹介
    注意 「件名」の**をそのままにしないで,必ず自分の学生番号 に修正して下さい.また,ABクラス別は指示にしたがって下さい.

  3. 電子メール配送 (SMTPとPOP3)

    電子メールの送受信をRubyスクリプトにより直接コマンド操作で実習します.こ れにより,実際にメールソフトが行っている動作を自分で確認します.

    • メールの受信

      メールの受信にはPOP3 (Post Office Protocol version3) が利用されます.メー ルの読み出しにはユーザの認証が必要になるので,ユー ザとの対話的なやり取りが行われます.使用されるコ マンドの代表的なものを以下に示します.

      STATダウンロード可能メールの一覧を得る
      LISTメールの一覧もしくは引数で指定したメールの情報を得る
      RETR引数で指定した番号のメールを読む
      DELE引数で指定した番号のメールに削除マークをつける
      RSET削除マークを取り消す
      QUIT削除マークのついたメールを削除して終了する

      これについてもSylpheedの「ログウィンドウ」で実際の動作は確認できます.以 下に例を示します.

      
      POP3サーバ: mag2.riko.shimane-u.ac.jp に接続中...
      POP3< +OK QPOP (version 2.53) at mag2.riko.shimane-u.ac.jp starting.  <12102.1022425896@mag2.riko.shimane-u.ac.jp>
      POP3> USER nawate
      POP3< +OK Password required for nawate.
      POP3> PASS ********
      POP3< +OK nawate has 1 message (2498 octets).
      POP3> STAT
      POP3< +OK 1 2498
      POP3> LIST
      POP3< +OK 1 messages (2498 octets)
      POP3> RETR 1
      POP3< +OK 2498 octets
      POP3> DELE 1
      POP3< +OK Message 1 has been deleted.
      POP3> QUIT
      POP3< +OK Pop server at mag2.riko.shimane-u.ac.jp signing off.
      

      上記以外のコマンドで場合によっては使うことの多いものに次の二つがあります.

      TOP引数として与えた行数分だけメール本文を表示する
      UIDLメールのID表示

      TOP コマンドは大量のメールを日常的に受信している場合に,メール の先頭の指定した行だけを一覧表示するものであり, メールを全て受信せずに必要なものをあらかじめ確認 してから受信できるようになります.UIDL はメールにつけられたユニークなIDを表示するもので, メッセージをサーバに残す設定にしている場合,既読 と未読の区別を行うのに使われたりします.

    • メール受信スクリプト

      以下のスクリプトにより上記の動作を自分で対話的に行ってみましょう.スクリ プトは先週と同様の書籍のp.296に出ているものです.

      ダウンロード用ファイルも用意しました.右クリックで保存してください.

      
      #!/usr/bin/ruby
      
      require "socket"
      
      server, port = ARGV
      sock = TCPSocket.open(server, port)
      
      begin
        t = Thread.start do
          while b = sock.gets
            print b
          end
          exit
        end
        while line = $stdin.gets
          line.chop!
          break if line == ".."
          sock.print line, "\r\n"
        end
        t.exit
      ensure
        sock.close
      end
      

      このスクリプトの実行は,ターミナルでまずサーバへの接続から始めます.

      $ ruby pop.rb matsu.ipc.shimane-u.ac.jp 110

      最後の110というのはPOP3が使うポート番号です.以下にサーバからの応答と自 分で入力すべき情報について色分けして紹介しておきます.

      
      +OK QPOP (version 3.1.2) at lxfs.cosmos.shimane-u.ac.jp starting.  
      
      
      USER s0340**
      
      
      +OK Password required for s0340**.
      
      
      PASS hogehogehoge
      
      
      +OK s0340** has 1 visible message (0 hidden) in 1378 octets.
      
      
      LIST
      
      
      +OK 1 visible messages (1378 octets)
      1 1378
      .
      
      
      RETR 1
      
      
      +OK 1378 octets
      >From bin  Mon May 27 00:17:50 2002
       .....
      
      
      QUIT
      
      
      +OK Pop server at lxfs.cosmos.shimane-u.ac.jp signing off.
      

      全体を眺めてみると,Sylpheedの「ログウィンドウ」と同じような内容になっているのが分かるでしょ う.なお,ここでは入力したパスワードが見えてしまうので,それなりに注意し てください.また,LISTコマンドで実際に得られるメールの数はそれぞれ異なり ますので上と同じにならない場合もあります.DELEコマンドは使用しないように しましょう.Sylpheedであとから読めなくなります.

      注意事項

      • コマンドは大文字で紹介していますが,小文字でも同様の動作となります.

      • コマンド入力中は入力内容の修正はできません.間違えた場合にはあきらめ てEnterキーを押して,やり直しましょう.

      • 作業は必ず QUIT で終わりましょう.あるユーザのメールボック スに対して,どこからかPOP3で接続中はそれ以外の場所からの接続はでき ません.複数の場所から同時にコマンドが送られた場合ファイルの一貫性 が失われるためです.作業中にはデータにはロックがかかります.(ロック ファイルと言うものが作られています.)このロックを解除するのが終了作 業です.きちんと終了しないとロックが解除されず,次回以降メールを読 むことができません.

  4. バイナリーデータ添付

    先週の授業でbase64方式によるバイナリーデータのASCIIコード化を学習しまし た.今週は,自分で実際にテキストデータや画像データを添付する手順をスクリ プトにより実習します.いくつかの細かい作業が続きますので,間違いの無いよ うに慎重に作業しましょう.

    • メール送信スクリプト

      先週の授業で紹介していたSMTPによるメール送信スクリプトを次のように修正しました. これは,自分で添付書類のついたメールのヘッダを見てみると分かりますが, MIMEによる拡張形式を利用することをメールの中で宣言する行が増えているだけ です.ダウンロードはこちらから.

      
      #!/usr/bin/ruby
      
      require "socket"
      require "kconv"
      require "timeout"
      
      class Client
        def initialize(host, port)
          @host, @port = host, port
        end
        def open
          timeout(60) do
            @sock = TCPSocket.open(@host, @port)
          end
        end
        def close
          @sock.close
        end
        def puts(x)
          $stdout.puts x if $DEBUG
          @sock.print x, "\r\n"
        end
        def wait(regex, sec = 60)
          timeout(sec) do
            line = @sock.gets
            $stdout.puts line if $DEBUG
            unless regex =~ line
      	raise "Response line not matches #{regex.inspect}"
            end
          end
        end
      end
      
      class SmtpMail < Client
        attr_accessor :domain, :from, :to, :subject, :contents
        def initialize(host, from, to, subject, contents)
          @from, @to, @subject, @contents = from, to, subject, contents
          (myname, @domain), = @from.scan(/(.+)@(.+)/)
          super(host, 25)
        end
        def open
          super
          wait(/^220\s/)
          puts("HELO #@domain"); wait(/^250\s/)
        end
        def send
          puts("MAIL FROM:#@from"); wait(/^250\s/)
          puts("RCPT TO:#@to");     wait(/^250\s/)
          puts("DATA");             wait(/^354\s/)
          puts("Subject: #@subject") if @subject
          puts("Mime-Version: 1.0")
          puts("Content-Type: multipart/mixed; boundary=\"a0a0a0a0\"")
          puts("")
          @contents.each do |line|
            puts Kconv.tojis(line.sub(/^\./, '..')).sub(/\r?\n?\z/, "")
          end
          puts("."); wait(/^250\s/)
        end
        def quit
          puts("QUIT"); wait(/^221\s/)
        end
      end
      
      host, to, from, subject = ARGV
      unless subject
        puts "Example: mail.rb server her@her.domain me@my.domain SUBJECT < mail.txt"
        exit
      end
      
      contents = $stdin.readlines
      mail = SmtpMail.new(host, to, from, subject, contents)
      mail.open
      mail.send
      mail.quit
      mail.close
      

      赤で印した修正部分で,メール本文と添付書類との区別をつけるための境界を a0a0a0a0 としています.この文字列がデータの中に出てく るとそこを境界と判断します.なので,何かの間違いでこの文字列がデー タ中に出てくると動作がおかしくなりますが,多分大丈夫でしょう.自 分では境界以外で使用しないように注意してください.

    • コード化

      UNIXには標準で先週紹介した uuencode コマンドがついていますが, -m オプションをつけることによりbase64形式での利用が可能です.今回は これを利用してコード化をターミナルで行います.

      1. 文字ファイルのコード化

        テキストファイルはメールで送受信できますが,メールの本文ではなく独立した ファイルとして扱うためには添付書類形式とすることが良くあります.この授業 のテストの提出方法もそうなっています.まずは,適当なテキストファイルを用 意して,それをコマンドでコード化してみましょう.

        用意したファイルを sample.txt とすると,コマンドは次のようにな ります.

        $ uuencode -m sample.txt < sample.txt

        uuencode コマンドは標準入力の内容をコード化して標準出力に出しま す.オプションの -m はMIME形式の意味で,これにより base64になります.今の場合,あらかじめ用意しているファイルを利用 するので,リダイレクトを利用して入力しています.例えば,内容が

        abcdefghijklmn

        であるファイルを変換すると,次のように出力されます.

        begin-base64 644 sample.txt
        YWJjZGVmZ2hpamtsbW4K
        ====

        ファイル名を sample.txt とするように指定してコマンドを実行した ので,結果表示の中にも sample.txt と表示されていますが,これは 自分で自由に変更できます.

        結果をファイルに保存するには,やはりリダイレクトを利用して,

        $ uuencode -m sample.txt < sample.txt > text.txt

        のようにします.ここでも,出力するファイル名は自由に設定できます.

      2. 画像ファイルのコード化

        画像ファイルについても試してみましょう.そのためにはまず画像を作成する必 要があります.Gimpを使って簡単な画像を作ってみましょう.

        「ファイル」メニューの「新規」を選択し,図1のウィンドウで画像のサイズを 48×48ピクセルとします.(サイズは適当で良いですが,大きすぎると面倒なの で小さなものにしましょう.)

        図1 新規ウィンドウサイズ設定画面

        現れるのは,図2に示すような小さなウィンドウです.ここに,ペンや筆を使っ て適当なものを描き入れましょう

        図2 キャンバス

        描き終わったら画像を保存します.右クリックで出てくるメニューから「ファイ ル」「保存」と進んで,適当な名前(例えば,image.png)をつけて保存 します.では,次にコード化してみましょう.やはりコマンドで実行します.

        $ uuencode -m image.png < image.png

        結果は画面に表示されますが,ファイルとして保存するには先ほどと同様にリダ イレクトを利用します.

        画像ファイルの実態を見るために,例えば,

        $ cat image.jpg

        などとすることが可能です.テキストファイルと違ってバイナリ符号化されてい るので,8ビットの制御コードなどが含まれており,画面に表示できない状態に なっているのが確認できるでしょう.

        もし,上記作業でターミナルの表示自体がおかしくなった場合には,文字が表示 されないままでも構いませんので,次のコマンドをそのターミナルで実行しましょ う.元に戻るはずです.

        $ setterm -reset

    • メール本文の作成

      準備ができたところで,メールの本文を作成します.手動でメールの送信を行う 関係で,本文と添付部分も自分で作成します.次のようなテキストファイルを作 りましょう.

      This is a multi-part message in MIME format.
      
      --a0a0a0a0
      Content-Type: text/plain; charset=ISO-2022-JP
      Content-Transfer-Encoding: 7bit
      
      ここにメールの本文を適当に入れてください.内容は自由に.
      
      --a0a0a0a0
      Content-Type: text/plain;
       name="text.txt"   <-- 自分で設定したファイル名
      Content-Disposition: attachment;
       filename="text.txt"   <-- 自分で設定したファイル名
      Content-Transfer-Encoding: base64
      
      ここに先ほど作成したテキストファイルのコード化された部分を張り付けます.
      コードの部分だけで構いません.
      
      --a0a0a0a0
      Content-Type: image/png
       name="image.png"   <-- 自分で設定したファイル名
      Content-Disposition: attachment;
       filename="image.png"   <-- 自分で設定したファイル名
      Content-Transfer-Encoding: base64
      
      ここには先ほどコード化した画像ファイルを張り付けます.
      
      

      これで本文の出来上がりです.

    • 送信

      では,送信しましょう.方法は先週と同じですが,スクリプトのファイル名が変 わっているので注意して下さい.先ずは,自分宛に送ってみましょう.

    • 受信

      受信はSylpheedを使ってみましょう.ちゃんとファイルができていれば,見事に 添付書類つきのメールが送られて来るはずです.テキストや画像はツールが無く てもSylpheedの中で見ることができます.無事に見えましたか?

      画像を実際に確認するための,一番簡単なツールは「エレクトリックアイズ」で す.「プログラム」メニューの中の「グラフィック」にあります.右クリックで ファイルメニューを呼び出します.また, ターミナルからは ee と言うコマンドに見たい画像ファイルを引数と して与えれば,画像を開きながら起動することができます.

      $ ee image.gif &

  5. 小テスト

    授業の終了20分前くらいに小テストを実施します.アナウ ンスに注意してください.また,提出は電子メールにより行いますので,メール の送信準備は忘れないでいて下さい.

    Aクラス小テスト
    Bクラス小テスト

  6. 宿題

    授業の終りに宿題の説明をしますので,アナウンスに注意してください.

    Aクラス宿題
    Bクラス宿題


目次ページへ戻る