The AWK~plus Language Specification
AWK~plus
AWK~plus の入力ファイルは、 URL 指定による
一般ファイルと同じインターフェイスでの読み込みが可能。
さらに、ソケット通信機能を利用することにより、TCP/IP, UDP での双方向通信が可能になりました。
ファイル名:
"inet://PROTOCOL/LOCAL-PORT/REMOTE-HOST/REMOTE-PORT
[
/接続タイムアウト ] [ /#文字コードセット ]"
- PROTOCOL:
- 通信プロトコルを指定する (tcp または udp)
- LOCAL-PORT
- このコンピュータのローカルポートを使用して通信する
(TCP/IP ならサーバとして動作)
- REMOTE-HOST
- 接続先の IP アドレス または ホスト名
- REMOTE-PORT
- 接続先のポート番号
- 接続タイムアウト (オプション)
- 接続タイムアウトを、秒単位で指定する
- #文字コードセット (オプション)
- 文字コードセットを指定する
双方向パイプ: |&
- print[f] |&
ファイル名
- ファイル名 |&
getline の形式で使用する。 (AWK~plus では、'<', '>' 指定も可能)
|
|
daytime
は人が読める形式で時間を出力するサービスで、現在の時刻をテキスト形式で返す。
公開NTPサーバにアクセス
make
daytime
$(PLUS) Daytime.awk /inet/tcp/0/time.xmission.com/daytime
# Thu Jun 30 00:03:56 2011
BEGIN {
inet = ARGV[1]
inet
|& getline
print
"#", $0
close(inet)
}
UDPディレクティッド・ブロードキャストで送信
UDP通信では複数クライアントでの同時受信が可能。
make udps
# UDPサーバ
$(PLUS) DaytimeServer.awk /inet/udp/0/localhost/8813
make udp
# UDPクライアント
$(PLUS) Daytime.awk /inet/udp/8813/localhost/0
# Thu Jun 30 15:05:05 JST 2011
BEGIN {
inet = ARGV[1]
while(1) {
if (inet
~ /tcp/) printf "" |& inet #
TCP/IP: 空文字を送信しクライアント接続を待つ
print
strftime() |& inet
if (inet
~ /tcp/) close(inet) # TCP/IPなら閉じる
system("sleep 10")
}
}
Webサーバとクライアント (ブラウザ) 間で、
ウェブページを送受信すプロトコルで、要求メッセージに対して応答メッセージが返される。
検索エンジンにアクセス
検索エンジンにアクセスして、検索結果を表示する。
make http
$(PLUS) Http.awk www.google.co.jp /search?q=AWK~plus
BEGIN { # http
Client
host = ARGV[1]
query = ARGV[2]
inet = "/inet/tcp/0/" host "/80/"
printf
"GET %s%s HTTP/1.0\r\n\r\n",
host, query |& inet
while (0 < (inet |&
getline))
print
close(inet)
}
サイトによっては、こんな芸当も可能。
make query
$(PLUS) Cat.awk http://search.yahoo.co.jp/search?p=awk~plus
# Cat.awk
1
サーバの多重スレッド化
echoサーバを、多重スレッド化する例を下記に示す。
make tcpes
$(PLUS) EchoServer.awk /inet/tcp/8807/localhost/0
make tcpe
$(PLUS) Echo.awk /inet/tcp/0/localhost/8807
BEGIN {
# echo Server
inet = ARGV[1]
T[1]
= Future(.echo("A")) #
スレッドで実行
T[2] =
Future(.echo("B")) #
Join(T)
# 完了を待ち合わせる
}
function echo(id)(line)
{ #
この関数はスレッドで動作する
while(1) {
while (0
< (inet |& getline line)
&& "" != line) {
print
id, line |& inet
#
空行を受信するまで応答を返す
}
close(inet)
}
}
BEGIN { # echo
Client
inet = ARGV[1]
for (i = 1; i <= 3; i++) {
print strftime() |& inet
if (0
< (inet |& getline))
print
}
print
"" |& inet
#
空行を送信
close(inet)
}