Adobe AIR で UDP Socket(DatagramSocket)
以前 ARDrone を Flash(AIR) で飛ばして遊んでるときに使用していた DatagramSocket。
これ、実案件では年に一回使うか使わないかだったりして、必要な時はいろいろ忘れているので…自分用メモ。
・ドキュメントクラス
package
{
import com.bit101.components.InputText;
import com.bit101.components.Label;
import com.bit101.components.PushButton;
import com.bit101.components.TextArea;
import flash.desktop.NativeApplication;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.DatagramSocket;
import utils.InterfaceUtil;
[SWF( width = '330', height = '250', frameRate = '30', backgroundColor = '0xFFFFFF' )]
/**
*
* @author mousepancyo
*/
public class UDPSocketEx extends Sprite
{
private var datagramSocket:DatagramSocket;
private var _msg:TextArea;
private var _targetInput:InputText
private var _msgInput:InputText;
private var _btSend:PushButton;
private var _udpSocket:UDPSocketControler;
public function UDPSocketEx()
{
setup();
NativeApplication.nativeApplication.addEventListener( Event.EXITING, exit );
_msg.text = "Bindable Addresses: \n" + InterfaceUtil.getBindableAddresses().toString();
}
private function setup():void
{
_udpSocket = new UDPSocketControler( InterfaceUtil.getBindableAddresses());
_udpSocket.addEventListener( "receved", onDataReceived );
_udpSocket.setup();
_msg = new TextArea( this, 10, 80 );
_msg.width = 310;
var lab1:Label = new Label( this, 10, 201, "Target IP" );
_targetInput = new InputText( this, 60, 201, _udpSocket.localIP );
var lab2:Label = new Label( this, 10, 221, "Input Msg" );
_msgInput = new InputText( this, 60, 221 );
_msgInput.width = 150;
_btSend = new PushButton( this, 220, 220, "Send Message", sendMsg );
_msgInput.enabled = _targetInput.enabled = _btSend.enabled = false;
var btConnect:PushButton = new PushButton( this, 60, 50, "Connect", onConnect );
var btDisConnect:PushButton = new PushButton( this, 220, 10, "Dis Connect", onDisConnect );
btDisConnect.enabled = false;
var lab3:Label = new Label( this, 10, 11, "My IP" );
var localInput:InputText = new InputText( this, 60, 11, _udpSocket.localIP );
var lab4:Label = new Label( this, 10, 31, "Port No" );
var portInput:InputText = new InputText( this, 60, 31, "55555" );
function onConnect( e:MouseEvent ):void
{
btConnect.removeEventListener( MouseEvent.CLICK, onConnect );
btConnect.enabled = localInput.enabled = portInput.enabled = false;
_msgInput.enabled = _targetInput.enabled = _btSend.enabled = btDisConnect.enabled = true;
//socketSetup();
_udpSocket.connect( int( portInput.text ));
_msg.text = _udpSocket.msg;
btDisConnect.addEventListener( MouseEvent.CLICK, onDisConnect );
}
function onDisConnect( e:MouseEvent ):void
{
btDisConnect.removeEventListener( MouseEvent.CLICK, onDisConnect );
btConnect.enabled = localInput.enabled = portInput.enabled = true;
_msgInput.enabled = _targetInput.enabled = _btSend.enabled = btDisConnect.enabled = false;
_udpSocket.disConnect();
_msg.text = _udpSocket.msg;
btConnect.addEventListener( MouseEvent.CLICK, onConnect );
}
}
private function onDataReceived( e:Event ):void
{
_msg.text = _udpSocket.msg + "\n" + _msg.text;
}
private function sendMsg( e:MouseEvent ):void
{
var ip:String = _targetInput.text;
var msg:String = _msgInput.text;
_udpSocket.send( ip, msg );
}
private function exit( e:Event ):void
{
_udpSocket.disConnect();
}
}
}
・UDP接続用のクラス
package
{
import flash.events.DatagramSocketDataEvent;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.net.DatagramSocket;
import flash.utils.ByteArray;
/**
*
* @author mousepancyo
*/
public class UDPSocketControler extends EventDispatcher
{
private var datagramSocket:DatagramSocket;
private var _bindAdress:Array;
public var msg:String;
// My IPAdress
private var _localIP:String;
// Target IPAdress
private var _targetIP:String;
// Port Number
private var _port:int;
/**
* Getter
*/
public function get localIP():String
{
return _localIP;
}
public function get targetIP():String
{
return _targetIP;
}
/**
* Constractor
*/
public function UDPSocketControler( bindAdress:Array, target:IEventDispatcher = null )
{
super( target );
_bindAdress = bindAdress;
}
public function setup():void
{
_localIP = _bindAdress[ 0 ];
if ( _localIP.substr( 0, 3 ) == "127" )
{
_localIP = _bindAdress[ 1 ];
}
}
/**
* UDP Connect
*/
public function connect( port:int ):void
{
_port = port;
datagramSocket = new DatagramSocket();
if ( datagramSocket.bound )
{
datagramSocket.close();
}
datagramSocket.addEventListener( DatagramSocketDataEvent.DATA, onReceved );
// Bind the socket
datagramSocket.bind( _port, _localIP );
// Listener
datagramSocket.receive();
msg = "Bound to: " + localIP + ":" + _port;
}
/**
* DisConnect
*/
public function disConnect():void
{
try
{
datagramSocket.close();
msg = "datagramsocket closed.";
}
catch ( e:Error )
{
msg = e.message;
}
}
/**
* Send
*/
public function send( ip:String, msg:String ):void
{
// message in ByteArray
var data:ByteArray = new ByteArray();
data.writeUTFBytes( msg );
// Send msg
datagramSocket.send( data, 0, 0, ip, _port );
}
// Recever
private function onReceved( e:DatagramSocketDataEvent ):void
{
msg = "Received from IP: " + e.srcAddress + " Port: " + e.srcPort + "\n> " + e.data.readUTFBytes( e.data.bytesAvailable );
dispatchEvent( new Event( "receved" ));
}
}
}
・InterfaceUtil クラス
package utils
{
import flash.net.IPVersion;
import flash.net.InterfaceAddress;
import flash.net.NetworkInfo;
import flash.net.NetworkInterface;
public class InterfaceUtil
{
private static var bindableAddressesCache:Array;
public static function getBindableAddresses():Array
{
if (bindableAddressesCache) return bindableAddressesCache;
var addresses:Array = new Array();
var netinfo:NetworkInfo = NetworkInfo.networkInfo;
var netifs:Vector.<NetworkInterface> = netinfo.findInterfaces();
for each (var netif:NetworkInterface in netifs)
{
for each (var addr:InterfaceAddress in netif.addresses)
{
if (addr.ipVersion == IPVersion.IPV4) {
addresses.push(addr.address);
}
}
}
bindableAddressesCache = addresses;
return addresses;
}
}
}
動作確認用サンプルアプリはこちら。
Mac 用と Windows 用のキャプティブランタイム AIR アプリを一緒にアーカイブしてるのでちょっと容量が大きいです…
