2010年10月6日水曜日

/inet = AWKからインターネットにアクセスする方法(Gawk専用) - AWK

AWKの入出力とコマンド実行機能
AWKのインターネット接続機能
○(確認中)Cygwin △(確認中)Gawk on Windows ×Gawk ×mawk32 ×Mawk ×awk
最新版のGawkは、インターネットにアクセスする事が出来ます。

o Gawk のユーザーズガイド(for 3.1.8)によると、TCP / UDP の他、生パケット(RAW)も扱う事が出来るとの事でした。
o 動作確認したのは、TCPだけです。他のプロトコルについては、確認し次第、このメモを更新します。


**** 書式
--------
接続用文字列 = "/inet/プロトコル名/自分のポート番号/相手のホスト名/相手のポート番号"
--------

o 特殊ファイル名と同じような形で指定します。入出力する時は |& で繋ぎます。
o 接続用文字列 -- 入出力の時に使うキーワードを決めます。
o プロトコル名 -- 3種類あります。tcp / udp / raw
   + Webページを取得する場合は、tcp を指定します。
o 自分のポート番号 -- 0 を指定すると、任意の番号を割り当ててくれます。
   + サーバーを作る場合は、待ち受けるTCPやUDPの番号を指定します。
o 相手のホスト名 -- アクセスしたい相手のドメイン名を指定します。
   + アクセス先が http://example.com/a.htm の時、example.com を指定します。
   + アクセス先が http://example.com:8080/a.htm の時も、example.com を指定します。
   + Gawk on Windows 3.1.7の場合、IPアドレスは指定出来ないみたいです。
      + 127.0.0.1 を指定するとエラーになりました。
   + サーバーを作る場合、0 を指定すると、任意の相手を待ち受ける事が出来ます。
o 相手のポート番号 -- アクセスしたい相手のポート番号を指定します。
   + アクセス先が http://example.com/a.htm の時は、80 を指定します。httpでもOKです。
   + アクセス先が http://example.com:8080/a.htm の時は、8080 を指定します。
   + サーバーを作る場合、0 を指定すると、相手が接続する番号に合わせてくれます。


**** 使用例
o http://example.com/ のトップページのHTMLファイルを取得する例です。
o 実行コマンド
--------
gawk -v BINMODE=3 -f a.awk > out.htm
--------

o AWKプログラム
--------
BEGIN {
  RS = "\r\n";
  ORS = "";
  www = "/inet/tcp/0/example.com/80";
  print "GET / HTTP/1.0\r\n\r\n" |& www; # 送信の終わりは 2回連続で改行します

  # 先頭にヘッダー情報があります。ヘッダーの終わりは空行(= \r\n\r\n)
  while ((www |& getline) > 0 && length($0) > 0) {
    print $0 RT > "/dev/stderr";
  }

  # Webページを取得します。
  while ((www |& getline) > 0) {
    print $0 RT;
  }
  close(www);
}
--------

o 行末のセミコロンは、C言語の書き方に合わせました。無くても動きます。


**** 機能
o 入出力の形を拡張する事で、インターネットにアクセスする事が出来ます。
o 形式は、特殊ファイル名と同じような形で指定します。
o 入出力関数は、双方向パイプの形で使います = 特殊ファイル名を |& で繋ぎます。
--------
読み込みは、インターネット接続用文字列 |& getline
書き出しは、print 送りたいデータ |& インターネット接続用文字列
終わったら、close(インターネット接続用文字列)
--------

o 入出力系の関数の使い方については
    + 「getline = ファイル(やパイプ)から1行読み込む
    + 「print = ファイルなどに書き出す
    + 「printf = 文字列を組み立ててファイルなどに書き出す
    + 「close = 開いたファイル(やパイプ)を閉じる
o その他のキーワードについては
    + 「BINMODE = バイナリモードで読み書きする
    + 「/dev/stderr = 標準エラー出力を示すファイル名
    + 「RS = 1行読み込む時の改行文字
    + 「ORS = printを使って書き出す時の改行文字
    + 「RT = 最後に読み込んだ行の改行文字
o この機能をサポートしていない処理系があります。

** 処理系に依存する機能
o Gawk on Windows 3.1.7の場合、以下の制限があります。
   + 相手のホスト名に、IPアドレスを指定する事は出来ません。(例。127.0.0.1)
   + この機能を、同時に複数のAWKプログラムで使う事は出来ません。
o これらの制限は、Cygwin版 Gawk 3.1.8 にはありません。

o この他、Gawk on Windows 3.1.7の場合、インターネットへのアクセス時に限り、自動的にバイナリモードになります。
   + インターネットアクセス時の改行コードは、\r\nの形で指定します。
   + ファイルアクセスの方は、何も指定しないとテキストモードです。(改行コードは \nで指定)
o Cygwin版やUNIX版と動きを合わせる時は、コマンド実行時に「 -v BINMODE=3」を指定します。
   + 常にバイナリモードで動作するようにします。


**** メモ
o この機能を何度も使うような時は、関数にする方法が良さそうです。
o Gawkが実装しているのは低レベルの通信です。なんでも出来ますが、そのまま使うのは不便です。


**** 確認した処理系
o Gawk 3.1.8 (on Cygwin) -- 確認したのは TCP のみ
o Gawk on Windows 3.1.7 -- 制限事項あり。確認したのは TCP のみ
o Gawk for Windows 3.1.6 -- 非対応。|& の指定の所で文法エラー
o mawk MBCS (32bit版) 1.3.3 -- 非対応
o Mawk for Windows 1.3.3 -- 非対応
o original = the one true awk(updated May 1, 2007) -- 非対応


==
関連ページ:
    ▼AWKの入出力関数とコマンド実行機能▼ABC順
    ▼AWKのインターネット接続機能(Gawk専用)
    ▼AWKプログラムを書く▼ABC順
    ▼AWK
    ▼制作メモ
    > /dev/stdout = 標準出力を示すファイル名
    /dev/stderr = 標準エラー出力を示すファイル名
    > /inet/tcp を使った通信例。クライアントサーバー編(Gawk専用)
(2010年10月7日変更。使用例のAWKプログラムで、最後に改行を含まないページに対応)