ソケットFlash Player 9 以降、Adobe AIR 1.0 以降 ソケットとは、2 つのコンピュータープロセス間で確立されるネットワーク接続のタイプです。通常、これらのプロセスは、同じインターネットプロトコル(IP)ネットワークに接続している 2 台の異なるコンピューター上で実行されています。ただし、「local host」という名前の特殊な IP アドレスを使用すれば、接続された 2 つのプロセスを同じコンピューター上で実行することができます。 Adobe Flash Player は、クライアントサイドの伝送制御プロトコル(TCP)ソケットをサポートしています。Flash Player アプリケーションは、ソケットサーバーとして機能している別のプロセスに接続できますが、他のプロセスからの着信接続要求を受け入れることはできません。つまり、Flash Player アプリケーションは、TCP サーバーへの接続は可能ですが、サーバーとして機能することはできません。 Flash Player API には XMLSocket クラスも含まれています。XMLSocket クラスでは、Flash Player 固有のプロトコルを使用します。これにより、当該プロトコルを理解するサーバーと XML メッセージをやりとりできます。XMLSocket クラスは ActionScript 1 で導入され、後方互換性の維持のために、引き続きサポートされています。一般に、Socket クラスは、特に Flash XMLSocket との通信のために作成されたサーバーに接続する場合を除いて、新しいアプリケーションに対して使用する必要があります。 Adobe AIR によって、ソケットベースのネットワークプログラミング用のクラスがいくつか追加されます。AIR アプリケーションは、ServerSocket クラスを使用すれば TCP ソケットサーバーとして機能できます。また、SSL または TLS セキュリティが要求されるソケットサーバーには SecureSocket クラスを使用して接続できます。AIR アプリケーションは、DatagramSocket クラスを使用して、ユニバーサルデータグラムプロトコル(UDP)メッセージを送受信することもできます。 TCP ソケット伝送制御プロトコル(TCP)には、固定ネットワーク接続経由でメッセージを交換する方法が用意されています。TCP では、送信されたメッセージは、(大きなネットワークの問題が発生しない限り)正しい順序で到達することが保証されています。TCP 接続では、「クライアント」と「サーバー」が必要です。Flash Player はクライアントソケットを作成できます。Adobe AIR では、さらに、サーバーソケットも作成できます。 以下の ActionScript API が TCP 接続を提供します。
バイナリクライアントソケットバイナリソケット接続は、XML ソケットに似ていますが、クライアント / サーバー間で交換するデータが XML メッセージに限定されないという点が異なります。データはバイナリ情報として伝送されます。したがって、電子メールサーバー(POP3、SMTP、IMAP)やニュースサーバー(NNTP)など様々なサービスに接続できます。 Socket クラスSocket クラスを使用すると、ソケット接続を確立して生のバイナリデータを読み書きできます。Socket クラスは、バイナリプロトコルを使用するサーバーとの通信に役立ちます。バイナリソケット接続を使用すれば、POP3、SMTP、IMAP、NNTP など様々なインターネットプロトコルによる通信のコードを記述できます。この操作によって、アプリケーションから電子メールサーバーやニュースサーバーに接続することもできます。 Flash Player からサーバーに直接接続するには、サーバーが使用するバイナリプロトコルに従う必要があります。 バイト順序にビッグエンディアンを使用するサーバーと、リトルエンディアンを使用するサーバーがあります。「ネットワークバイト順序」がビッグエンディアンとされているため、インターネット上の大部分のサーバーはビッグエンディアンのバイト順序を使用しています。また、Intel® x86 アーキテクチャでリトルエンディアンが採用されているので、リトルエンディアンのバイト順序が使用されることもよくあります。データを送受信する対象のサーバーに適したエンディアンバイト順序を使用してください。IDataInput および IDataOutput インターフェイスで実行されるすべての操作と、これらのインターフェイスを実装するクラス(ByteArray、Socket、URLStream)では、デフォルトでビッグエンディアン形式(先頭が最上位バイト)を使用します。 Java と公式なネットワークバイト順序を一致させるために、このデフォルトのバイト順序が選択されました。使用するエンディアンを変更する場合は、endian プロパティを Endian.BIG_ENDIAN または Endian.LITTLE_ENDIAN に設定します。 ![]() 詳しくは、以下を参照してください。 セキュアなクライアントソケット(AIR)SecureSocket クラスを使用すると、セキュアソケットレイヤーバージョン 4(SSLv4)またはトランスポート層セキュリティバージョン 1(TLSv1)を使用しているソケットサーバーに接続できます。セキュアなソケットには 3 つのメリット(サーバー認証、データの整合性、メッセージの機密性)があります。ランタイムでは、サーバー証明書と、ユーザーの信頼ストアに格納されているルート証明機関証明書または中間証明機関証明書との関連付けを使用してサーバーを認証します。ランタイムでは、SSL および TLS プロトコル実装で使用されている暗号化アルゴリズムに基づいて、データの整合性およびメッセージの機密性を確保します。 SecureSocket オブジェクトを使用してサーバーに接続する場合、ランタイムでは証明書信頼ストアを使用してサーバー証明書を検証します。Windows および Mac では、オペレーティングシステムが信頼ストアを提供します。Linux では、ランタイムが独自の信頼ストアを提供します。 サーバー証明書が有効でないまたは信頼できないと判断されると、ランタイムは ioError イベントを送出します。SecureSocket オブジェクトの serverCertificateStatus プロパティを調べることにより、無効とされた理由を確認できます。有効または信頼された証明書を持たないサーバーとの通信は許可されません。 CertificateStatus クラスでは、想定される検証結果を表す文字列定数を定義します。
SecureSocket オブジェクトと通信する場合は、セキュアなプロトコルおよび有効で信頼された証明書が使用されているサーバーが必要です。その他の点では、SecureSocket オブジェクトと Socket オブジェクトの使用方法は同じです。 SecureSocket オブジェクトは一部のプラットフォームではサポートされていません。SecureSocket クラスの isSupported プロパティを使用すると、ランタイムが現在のクライアントコンピューターで SecureSocket オブジェクトの使用をサポートしているかどうかを確認できます。 詳しくは、以下を参照してください。 TCP ソケットの例:Telnet クライアントの構築この Telnet の例では、Socket クラスを使用してリモートサーバーに接続し、データを伝送する手法を示します。 この例は、次の手法を示します。
このサンプルのアプリケーションファイルを入手するには、www.adobe.com/go/learn_programmingAS3samples_flash_jp を参照してください。 Telnet アプリケーションのファイルは、Samples/Telnet フォルダーにあります。 このアプリケーションは次のファイルで構成されています。
Telnet ソケットアプリケーションの概要メイン TelnetSocket.mxml ファイルは、アプリケーション全体で使用するユーザーインターフェイス(UI)の作成に責任を負います。 このファイルでは、UI の他に、ユーザーを指定されたサーバーに接続するために、login() と sendCommand() の 2 つのメソッドも定義しています。 次のコードは、メインアプリケーションファイル内の ActionScript を示しています。 import com.example.programmingas3.socket.Telnet; private var telnetClient:Telnet; private function connect():void { telnetClient = new Telnet(serverName.text, int(portNumber.text), output); console.title = "Connecting to " + serverName.text + ":" + portNumber.text; console.enabled = true; } private function sendCommand():void { var ba:ByteArray = new ByteArray(); ba.writeMultiByte(command.text + "\n", "UTF-8"); telnetClient.writeBytesToSocket(ba); command.text = ""; } コードの 1 行目は、Telnet クラスをカスタム com.example.programmingas.socket パッケージから読み込みます。 コードの 2 行目は、Telnet クラスのインスタンス telnetClient を宣言します。このインスタンスは、後で connect() メソッドによって初期化されます。次に、connect() メソッドが宣言され、前に宣言された telnetClient 変数が初期化されます。このメソッドは、ユーザーが指定した Telnet サーバーの名前とポートを引き渡すほか、ソケットサーバーからのテキスト応答の表示に使用される表示リスト上の TextArea コンポーネントへの参照を引き渡します。 connect() メソッドの最後の 2 行は、Panel の title プロパティを設定し、Panel コンポーネントを有効にします。このコンポーネントを使用すると、リモートサーバーにデータを送信できます。メインアプリケーションファイル内の最後のメソッド、sendCommand() は、ユーザーのコマンドを ByteArray オブジェクトとしてリモートサーバーに送信するために使用されます。 Telnet クラスの概要Telnet クラスは、リモート Telnet サーバーへの接続と、データの送受信に責任を負います。 Telnet クラスは、次のプライベート変数を宣言します。 private var serverURL:String; private var portNumber:int; private var socket:Socket; private var ta:TextArea; private var state:int = 0; 最初の変数、serverURL は、ユーザーが指定した接続先サーバーアドレスを格納します。 2 番目の変数、portNumber は、Telnet サーバーが現在稼働しているポートの番号です。デフォルトでは、Telnet サービスはポート 23 上で稼働します。 3 番目の変数 socket は、serverURL 変数と portNumber 変数によって定義されたサーバーへの接続を試みる Socket インスタンスです。 4 番目の変数、ta は、ステージ上の TextArea コンポーネントインスタンスへの参照です。このコンポーネントは、リモート Telnet サーバーからの応答やエラーメッセージを表示するために使用されます。 最後の変数、state は、その Telnet クライアントがどのオプションをサポートするかを決定するために使用される数値です。 前に述べたように、Telnet クラスのコンストラクター関数は、メインアプリケーションファイル内の connect() メソッドによって呼び出されます。 Telnet コンストラクターは、server、port および output の 3 つのパラメーターを受け取ります。server パラメーターと port パラメーターは、Telnet サーバーが稼働しているサーバーの名前とポート番号を指定します。最後のパラメーター output は、サーバーの出力がユーザーに対して表示されるステージ上の TextArea コンポーネントインスタンスへの参照です。 public function Telnet(server:String, port:int, output:TextArea) { serverURL = server; portNumber = port; ta = output; socket = new Socket(); socket.addEventListener(Event.CONNECT, connectHandler); socket.addEventListener(Event.CLOSE, closeHandler); socket.addEventListener(ErrorEvent.ERROR, errorHandler); socket.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler); socket.addEventListener(ProgressEvent.SOCKET_DATA, dataHandler); Security.loadPolicyFile("http://" + serverURL + "/crossdomain.xml"); try { msg("Trying to connect to " + serverURL + ":" + portNumber + "\n"); socket.connect(serverURL, portNumber); } catch (error:Error) { msg(error.message + "\n"); socket.close(); } } ソケットへのデータの書き込みソケット接続にデータを書き込むには、Socket クラス内の任意の書き込みメソッドを呼び出します。これらの書き込みメソッドには、writeBoolean()、writeByte()、writeBytes()、writeDouble() などがあります。次に、flush() メソッドを使用して、出力バッファー内のデータをフラッシュします。Telnet サーバー内では、データは writeBytes() メソッドを使用してソケット接続に書き込まれます。このメソッドは、パラメーターとしてバイト配列を受け取り、それを出力バッファーに送信します。writeBytesToSocket() メソッドは次のとおりです。 public function writeBytesToSocket(ba:ByteArray):void { socket.writeBytes(ba); socket.flush(); } このメソッドは、メインアプリケーションファイルの sendCommand() メソッドによって呼び出されます。 ソケットサーバーからのメッセージの表示ソケットサーバーからメッセージを受け取るか、イベントが発生すると、カスタム msg() メソッドが呼び出されます。このメソッドは、ステージ上の TextArea に文字列を付加し、カスタム setScroll() メソッドを呼び出します。それによって、TextArea コンポーネントは最下部までスクロールします。msg() メソッドは次のとおりです。 private function msg(value:String):void { ta.text += value; setScroll(); } TextArea コンポーネントの内容を自動的にスクロールしなかった場合、サーバーからの最新の応答を参照するには、テキスト領域にあるスクロールバーを手動でドラッグする必要があります。 TextArea コンポーネントのスクロールsetScroll() メソッドには、TextArea コンポーネントの内容を垂直方向にスクロールする 1 行だけの ActionScript が含まれており、これにより、ユーザーは返されたテキストの最後の行を見ることができます。次のコードは、setScroll() メソッドを示しています。 public function setScroll():void { ta.verticalScrollPosition = ta.maxVerticalScrollPosition; } このメソッドは、現在表示されている文字の一番上の行の行番号を示す verticalScrollPosition プロパティを設定し、そのプロパティを maxVerticalScrollPosition プロパティの値に設定します。 XML ソケットXML ソケットを使用すると、明示的に閉じるまで開いたままの、リモートサーバーへの接続を作成できます。サーバーとクライアント間で、XML などのストリングデータを交換できます。XML ソケットサーバーを使用するメリットは、クライアントが明示的にデータを要求する必要がないことです。サーバーは要求に対してデータを送信するために待機することなく、すべての接続済みのクライアントにデータを送信できます。 Flash Player およびアプリケーションサンドボックスの外部にある Adobe AIR コンテンツの XML ソケット接続では、ターゲットサーバー上にソケットポリシーファイルが存在することが必要です。詳しくは、Web サイトのコントロール(ポリシーファイル)およびソケットへの接続を参照してください。 XMLSocket クラスは、ファイアウォールをトンネリングによって自動的に通過することはできません。RTMP とは異なり、XMLSocket には HTTP トンネリング機能が備わっていないためです。HTTP トンネリングが必要な場合は、Flash Remoting または(RTMP をサポートする)Flash Media Server の使用をお勧めします。 アプリケーションセキュリティサンドボックスの外部にある、Flash Player または AIR アプリケーションのコンテンツから XMLSocket オブジェクトを介してサーバーに接続する場合、その接続方法と接続先に関して次のような制限が適用されます。
注意: XMLSocket オブジェクトと通信できるようにサーバーを設定することは、場合によっては困難が伴います。リアルタイムのインタラクティブ機能を必要としないアプリケーションでは、XMLSocket クラスではなく URLLoader クラスを使用してください。
XMLSocket クラスの XMLSocket.connect() メソッドと XMLSocket.send() メソッドを使用すると、ソケット接続を介してサーバーとの間で XML を転送できます。XMLSocket.connect() メソッドは、Web サーバーのポートに対してソケット接続を確立します。XMLSocket.send() メソッドは、ソケット接続で指定されたサーバーに XML オブジェクトを渡します。 XMLSocket.connect() メソッドを呼び出すと、アプリケーションによってサーバーへの TCP/IP 接続が開かれ、次のいずれかのイベントが発生するまでその接続が開いたまま維持されます。
XMLSocket クラスによるサーバーへの接続ソケット接続を確立するには、ソケット接続の要求を受け付けて Flash Player または AIR アプリケーションに応答を送るサーバーサイドアプリケーションを作成する必要があります。このようなサーバーサイドアプリケーションは、AIR または Java、Python、Perl などの別のプログラミング言語で作成できます。XMLSocket クラスを使用するには、サーバーコンピューターは XMLSocket クラスで使用されるシンプルプロトコルに対応したデーモンを実行する必要があります。
Java XML ソケットサーバーの作成および接続次のコードは、Java で作成した単純な XMLSocket サーバーの例です。接続を受け付け、受信したメッセージをコマンドプロンプトウィンドウに表示します。デフォルトでは新しいサーバーをローカルマシンのポート番号 8080 に作成しますが、サーバーを起動する際のコマンドラインでポート番号を変更することもできます。 新しいテキストドキュメントを作成し、次のコードを入力します。 import java.io.*; import java.net.*; class SimpleServer { private static SimpleServer server; ServerSocket socket; Socket incoming; BufferedReader readerIn; PrintStream printOut; public static void main(String[] args) { int port = 8080; try { port = Integer.parseInt(args[0]); } catch (ArrayIndexOutOfBoundsException e) { // Catch exception and keep going. } server = new SimpleServer(port); } private SimpleServer(int port) { System.out.println(">> Starting SimpleServer"); try { socket = new ServerSocket(port); incoming = socket.accept(); readerIn = new BufferedReader(new InputStreamReader(incoming.getInputStream())); printOut = new PrintStream(incoming.getOutputStream()); printOut.println("Enter EXIT to exit.\r"); out("Enter EXIT to exit.\r"); boolean done = false; while (!done) { String str = readerIn.readLine(); if (str == null) { done = true; } else { out("Echo: " + str + "\r"); if(str.trim().equals("EXIT")) { done = true; } } incoming.close(); } } catch (Exception e) { System.out.println(e); } } private void out(String str) { printOut.println(str); System.out.println(str); } } このドキュメントを SimpleServer.java という名前でハードディスクに保存し、Java コンパイラーでコンパイルして、SimpleServer.class という Java クラスを作成します。 コマンドプロンプトを開き、java SimpleServer と入力して XMLSocket サーバーを起動します。SimpleServer.class ファイルはローカルコンピューター上またはネットワーク上のどこに配置しても使用できます。Web サーバーのルートディレクトリに置く必要はありません。 ![]() アプリケーションから XMLSocket に接続するには、次のように XMLSocket クラスの新しいインスタンスを作成し、ホスト名とポート番号を指定して XMLSocket.connect() メソッドを呼び出します。 var xmlsock:XMLSocket = new XMLSocket(); xmlsock.connect("127.0.0.1", 8080); サーバーからデータを受信するたびに、data イベント(flash.events.DataEvent.DATA)が送出されます。 xmlsock.addEventListener(DataEvent.DATA, onData); private function onData(event:DataEvent):void { trace("[" + event.type + "] " + event.data); } XMLSocket サーバーにデータを送信するには、XMLSocket.send() メソッドを使用して XML オブジェクトまたは XML ストリングを渡します。Flash Player によってパラメーターが String オブジェクトに変換され、その内容に終端を示すゼロ(0)バイトを付加したデータが XMLSocket サーバーに送信されます。 xmlsock.send(xmlFormattedData); XMLSocket.send() メソッドは、データが正常に転送されたかどうかを示す値を返しません。データの送信中にエラーが発生した場合は、IOError エラーがスローされます。 ![]() 詳しくは、「XMLSocket」を参照してください。 サーバーソケットServerSocket クラスを使用すると、他のプロセスが伝送制御プロトコル(TCP)ソケットを使用してアプリケーションに接続できます。接続しているプロセスは、ローカルコンピューターまたはネットワークに接続された別のコンピューター上で動作できます。ServerSocket オブジェクトが接続要求を受信すると、connect イベントが送出されます。このイベントを伴って送出された ServerSocketConnectEvent オブジェクトには Socket オブジェクトが含まれています。それ以降は、この Socket オブジェクトを使用して他のプロセスと通信できます。 受信ソケット接続を監視するには:
ServerSocket オブジェクトは close() メソッドが呼び出されるまで、新しい接続を継続的に監視します。 次のコード例では、ソケットサーバーアプリケーションの作成方法を示します。この例では、ポート 8087 で受信接続を監視します。接続を受信すると、メッセージ(「Connected」という文字列)がクライアントソケットに送信されます。これ以降、サーバーで受信したメッセージはすべてクライアントにエコーバックされます。 package { import flash.display.Sprite; import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.events.ServerSocketConnectEvent; import flash.net.ServerSocket; import flash.net.Socket; public class ServerSocketExample extends Sprite { private var serverSocket:ServerSocket; private var clientSockets:Array = new Array(); public function ServerSocketExample() { try { // Create the server socket serverSocket = new ServerSocket(); // Add the event listener serverSocket.addEventListener( Event.CONNECT, connectHandler ); serverSocket.addEventListener( Event.CLOSE, onClose ); // Bind to local port 8087 serverSocket.bind( 8087, "127.0.0.1" ); // Listen for connections serverSocket.listen(); trace( "Listening on " + serverSocket.localPort ); } catch(e:SecurityError) { trace(e); } } public function connectHandler(event:ServerSocketConnectEvent):void { //The socket is provided by the event object var socket:Socket = event.socket as Socket; clientSockets.push( socket ); socket.addEventListener( ProgressEvent.SOCKET_DATA, socketDataHandler); socket.addEventListener( Event.CLOSE, onClientClose ); socket.addEventListener( IOErrorEvent.IO_ERROR, onIOError ); //Send a connect message socket.writeUTFBytes("Connected."); socket.flush(); trace( "Sending connect message" ); } public function socketDataHandler(event:ProgressEvent):void { var socket:Socket = event.target as Socket //Read the message from the socket var message:String = socket.readUTFBytes( socket.bytesAvailable ); trace( "Received: " + message); // Echo the received message back to the sender message = "Echo -- " + message; socket.writeUTFBytes( message ); socket.flush(); trace( "Sending: " + message ); } private function onClientClose( event:Event ):void { trace( "Connection to client closed." ); //Should also remove from clientSockets array... } private function onIOError( errorEvent:IOErrorEvent ):void { trace( "IOError: " + errorEvent.text ); } private function onClose( event:Event ):void { trace( "Server socket closed by OS." ); } }} 詳しくは、以下を参照してください。 UDP ソケット(AIR)ユニバーサルデータグラムプロトコル(UDP)は、ステートレスネットワーク接続経由でメッセージを交換する手段です。UDP では、メッセージの配信順序またはメッセージの配信自体が保証されません。UDP を使用すると、通常、オペレーティングシステムのネットワークコードでは、メッセージのマーシャリング、追跡および応答にかかる時間が短縮されます。したがって、一般的に、UDP メッセージが送信先のアプリケーションに到着するまでの遅延時間は TCP メッセージよりも短くなります。 UDP ソケット通信は、ゲームでの位置の更新や音声チャットアプリケーションの音声パケットなど、リアルタイムな情報を送信する必要がある場合に役に立ちます。このようなアプリケーションでは、ある程度のデータ損失は許容されるので、受信が保証されるよりも伝送待ち時間が短縮される方が重要です。その他の場合は、ほとんどすべての用途に TCP ソケットの方が適しています。 AIR アプリケーションでは、DatagramSocket クラスおよび DatagramSocketDataEvent クラスを使用して、UDP メッセージを送受信できます。UDP メッセージを送受信するには:
次のコード例では、アプリケーションで UDP メッセージを送受信する方法を示します。この例では、文字列「Hello」を含む単一メッセージを送信先コンピューターに送信します。また、すべての受信メッセージをトレースします。 package { import flash.display.Sprite; import flash.events.DatagramSocketDataEvent; import flash.events.Event; import flash.net.DatagramSocket; import flash.utils.ByteArray; public class DatagramSocketExample extends Sprite { private var datagramSocket:DatagramSocket; //The IP and port for this computer private var localIP:String = "192.168.0.1"; private var localPort:int = 55555; //The IP and port for the target computer private var targetIP:String = "192.168.0.2"; private var targetPort:int = 55555; public function DatagramSocketExample() { //Create the socket datagramSocket = new DatagramSocket(); datagramSocket.addEventListener( DatagramSocketDataEvent.DATA, dataReceived ); //Bind the socket to the local network interface and port datagramSocket.bind( localPort, localIP ); //Listen for incoming datagrams datagramSocket.receive(); //Create a message in a ByteArray var data:ByteArray = new ByteArray(); data.writeUTFBytes("Hello."); //Send the datagram message datagramSocket.send( data, 0, 0, targetIP, targetPort); } private function dataReceived( event:DatagramSocketDataEvent ):void { //Read the data from the datagram trace("Received from " + event.srcAddress + ":" + event.srcPort + "> " + event.data.readUTFBytes( event.data.bytesAvailable ) ); } }} UDP ソケットを使用する場合は、以下の事項を考慮してください。
詳しくは、以下を参照してください。 IPv6 アドレスFlash Player 9.0.115.0 以降では、IPv6(インターネットプロトコルバージョン 6)がサポートされています。IPv6 は、128 ビットのアドレスをサポートするインターネットプロトコルのバージョンです(32 ビットのアドレスをサポートする、以前の IPv4 プロトコルの機能を向上したものです)。ネットワークインターフェイスでの IPv6 のアクティブ化が必要になる場合があります。詳細については、データをホストするオペレーティングシステムのヘルプを参照してください。 ホストしているシステムで IPv6 がサポートされる場合、次に示すように、角括弧([])内に URL の IPv6 数値リテラルアドレスを指定できます。 [2001:db8:ccc3:ffff:0:444d:555e:666f] Flash Player では、以下の規則に従ってリテラル IPv6 値が返されます。
Flash Player で返される IPv6 の値には、以下の例外があります。
|
![]() |