Wake on LAN してみる

MacBook Pro を新調したことを機に 古い ノート PC に Linux を入れて Time Machine 用サーバとして使用することにしたのですが...
一日のほとんどを会社で過ごしているにも関わらず 常時 自宅で PC を立ち上げておくのも 何なので WOL (Wake on LAN) を使って 必要なときだけ リモートで起動することにしにてみた。

WOL を使って PC を起動するための アプリケーションは 世の中にいろいろとありますが、 WOL 自体 とっても簡単な仕様なので この機会に勉強も兼ねて JavaFX で自作することにしてみました。

WOL の仕組みは

起動したい PC がつなげられているネットワークに マジックパケットと呼ばれる特殊なパケットを ブロードキャストする
だけです。とっても簡単...
ところで マジックパケットとは
  • ブロードキャスト・アドレス(FF:FF:FF:FF:FF:FF)
  • 起動したい PC の NIC に割り当てられている MAC アドレス (AA:BB:CC:DD:EE:FF) × 16回
をつなぎ合わせたものです。こんなイメージ...
FFFFFFFFFFFFAABBCCDDEEFFAABBCCDDEEFF
AABBCCDDEEFFAABBCCDDEEFFAABBCCDDEEFF
AABBCCDDEEFFAABBCCDDEEFFAABBCCDDEEFF
AABBCCDDEEFFAABBCCDDEEFFAABBCCDDEEFF
AABBCCDDEEFFAABBCCDDEEFFAABBCCDDEEFF
AABBCCDDEEFFAABBCCDDEEFF
詳細な仕様は を参照するとよい。

マジックパケットJavaFX で表現すると

def macAddress = "AA:BB:CC:DD:EE:FF";

[ for (i in [1..6]) { 0xff as Byte },
  for (i in [1..16], b in macAddress.split(":")) { Integer.parseInt(b, 16) as Byte } ]
たったこれだけです。
たった 2行で マジックパケットを Byte[] で表現できてしまうのです。
リテラルで記述するよりも少ないコードで書けてしまうのは ちょっと感動ものです。
Java で書いたら 数十倍のコードが必要になるんだろうなぁ...

このコードはかなりトリッキーに見えますが JavaFX ではそれ程珍しいコードではありません。
JavaFX の一般的な言語仕様を使っているだけなので...
このコードには シーケンス (配列のようなもの) と for 式の主な特徴がほとんど含まれています。
これが理解できれば シーケンス と for式 が理解できたも同然ではないでしょうか。

JavaFX の for の特徴は 文 ではなく 式 であることです。
文と式の違いは結果を返すかどうかです。
JavaFX の for は シーケンスを返します。
次の式の結果は完全に等価です。
どちらも 0xff を 6個含む シーケンス を生成しています。

var broadcastAddress = [ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ];
var broadcastAddress = for (i in [1..6]) { 0xff };

もう一つの特徴は 多重ループを一つの for で記述できるところです。
以下の 2つの for式は全く同じ処理を表します。
どちらも 16 × 6 回 HOGE を出力します。

for (i in [1..16]) {
    for (j in [1..6]) {
        println("HOGE");
    }
}

// 多重ループの場合 カンマ区切りで記述する
for (i in [1..16], j in [1..6]) { println("HOGE"); }

マジックパケットを表すコードをよく見ると シーケンスの中に ([ ] の間に) 2つの for 式がふくまれています。
for 式は シーケンスを返しますので、一見 2次元のシーケンスになりそうですが、シーケンスには多次元はありません。
シーケンスの中にシーケンスを入れると1次元のシーケンスとして展開されます。
従って 次のシーケンスは完全に等価です。

[ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF ] 
[ for (i in [1..6]) { 0xff }, [ 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF ] ]

次回は実際にこのマジックパケットを使って Wake on LAN してみたいと思います。
うまくいくか 乞うご期待...