AIR.DatagramSocketでBroadcast
ローカルネット内のPCを調べるにはbroadcastを使えばよかろう。
ってことで、DatagramSocketでBroadcastのテスト。
まずは、DatagramSocketの待ち受け。
datagramSocket = new DatagramSocket(); datagramSocket.bind( 50000 ); datagramSocket.receive(); datagramSocket.addEventListener(DatagramSocketDataEvent.DATA, datagramSocket_dataHandler);
特定のポートにbindして、receiveを呼び出せば良い。
あとは通信があれば、イベントが呼ばれる。
んで、メッセージのbroadcast。
var data:ByteArray = new ByteArray(); data.writeUTF( MSG_SEARCH_NODE_BROADCAST ); datagramSocket.send(data, 0, 0, "192.168.0.255", 50000);
ByteArrayしか受け付けないので、生成して渡す。
ローカルネット内で十分なので、アドレスは「192.168.0.255」にする。
datagramSocketは待ち受け用にreceiveしているものを使いまわしても問題ないみたい。
注意が必要なのは、AIR 2 SDK beta2のLinux版ではbroadcastができないこと。
broadcastアドレスにsendすると例外が発生する。
ドキュメントにも非サポートと書いてあるので、まだ未完成なんでしょ。
Linuxメインで書いてたので、また、無駄にハマったよ・・・
実現しているものもあるので、おかしぃなぁと四苦八苦してたんですが、
こんなオチでした。
メッセージの受信はいつも通りイベント。
private function datagramSocket_dataHandler(event:DatagramSocketDataEvent):void { var msg:String = event.data.readUTF(); trace( "datagram socket data:" + msg + "(" + event.srcAddress + ")" ); if( msg == MSG_SEARCH_NODE_BROADCAST ) { // var data:ByteArray = new ByteArray(); data.writeUTF( MSG_NODE_NOTIFICATION ); // var datagramSocket:DatagramSocket = event.target as DatagramSocket; datagramSocket.send(data, 0, data.length, event.srcAddress, 50000); } }
Broadcastのメッセージだったら、返信を返す。
自身の情報としてIPアドレスなんかを返せばいいけど、
これはeventオブジェクトから取得できるので、メッセージにはのせなくてOK。
今のとこドキュメントには書いてないけど、eventオブジェクトからdatagramSocketが確保できたので、
こいつを使って返信する。
datagramSocketをメンバでもつ意味が少ないけど、
receiveしているdatagramSocketはアプリ側で持っておかないと、ちゃんと動かない。
まあ、ちゃんと閉じるためにも持っとけばいいか。
Broadcastテスト用の全ソース
今回は構造がシンプルなので、ソースは1個です。
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" initialize="initializeLogic()" close="closeLogic()"> <mx:Script> <![CDATA[ private function initializeLogic():void { // try { datagramSocket = new DatagramSocket(); datagramSocket.bind( 50000 ); datagramSocket.receive(); datagramSocket.addEventListener(DatagramSocketDataEvent.DATA, datagramSocket_dataHandler); // var data:ByteArray = new ByteArray(); data.writeUTF( MSG_SEARCH_NODE_BROADCAST ); datagramSocket.send(data, 0, 0, "192.168.0.255", 50000); } catch( e:Error ) { trace( e.message + ":" + e.name ); } } private function closeLogic():void { if( datagramSocket ) { datagramSocket.close(); } } private function datagramSocket_dataHandler(event:DatagramSocketDataEvent):void { var msg:String = event.data.readUTF(); trace( "datagram socket data:" + msg + "(" + event.srcAddress + ")" ); if( msg == MSG_SEARCH_NODE_BROADCAST ) { // var data:ByteArray = new ByteArray(); data.writeUTF( MSG_NODE_NOTIFICATION ); // var datagramSocket:DatagramSocket = event.target as DatagramSocket; datagramSocket.send(data, 0, data.length, event.srcAddress, 50000); } } static private const MSG_SEARCH_NODE_BROADCAST:String = "message search node broadcast"; static private const MSG_NODE_NOTIFICATION:String = "message node notification"; private var datagramSocket:DatagramSocket; ]]> </mx:Script> </mx:WindowedApplication>