ソケット

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 接続を提供します。

  • Socket - クライアントアプリケーションがサーバーに接続できるようにします。Socket クラスは受信接続を監視できません。

  • SecureSocket(AIR) - クライアントアプリケーションが信頼できるサーバーに接続して、暗号化された通信を確立できるようにします。

  • ServerSocket(AIR) - アプリケーションが受信接続を監視して、サーバーとして機能できるようにします。

  • XMLSocket - クライアントアプリケーションが XMLSocket サーバーに接続できるようにします。

バイナリクライアントソケット

バイナリソケット接続は、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 に設定します。

Socket クラスは、(flash.utils パッケージ内の)IDataInput および IDataOutput インターフェイスで定義されているすべてのメソッドを継承します。これらのメソッドは、Socket クラスからの読み取りおよび書き込みに使用する必要があります。

詳しくは、以下を参照してください。

セキュアなクライアントソケット(AIR)

SecureSocket クラスを使用すると、セキュアソケットレイヤーバージョン 4(SSLv4)またはトランスポート層セキュリティバージョン 1(TLSv1)を使用しているソケットサーバーに接続できます。セキュアなソケットには 3 つのメリット(サーバー認証、データの整合性、メッセージの機密性)があります。ランタイムでは、サーバー証明書と、ユーザーの信頼ストアに格納されているルート証明機関証明書または中間証明機関証明書との関連付けを使用してサーバーを認証します。ランタイムでは、SSL および TLS プロトコル実装で使用されている暗号化アルゴリズムに基づいて、データの整合性およびメッセージの機密性を確保します。

SecureSocket オブジェクトを使用してサーバーに接続する場合、ランタイムでは証明書信頼ストアを使用してサーバー証明書を検証します。Windows および Mac では、オペレーティングシステムが信頼ストアを提供します。Linux では、ランタイムが独自の信頼ストアを提供します。

サーバー証明書が有効でないまたは信頼できないと判断されると、ランタイムは ioError イベントを送出します。SecureSocket オブジェクトの serverCertificateStatus プロパティを調べることにより、無効とされた理由を確認できます。有効または信頼された証明書を持たないサーバーとの通信は許可されません。

CertificateStatus クラスでは、想定される検証結果を表す文字列定数を定義します。

  • Expired - 証明書の有効期限が切れています。

  • Invalid - 証明書が無効と判断される理由は様々です。例えば、証明書が変更されているまたは破損している場合もあれば、証明書のタイプが間違っている場合もあります。

  • Invalid chain - サーバーの証明書チェーン内に無効な証明書が 1 つ以上存在します。

  • Principal mismatch - サーバーのホスト名と証明書の共通名が一致しません。つまり、サーバーでは間違った証明書が使用されています。

  • Revoked - 発行元の証明機関によって証明書が失効されています。

  • Trusted - 証明書は有効で信頼されています。SecureSocket オブジェクトでは、有効で信頼された証明書を使用しているサーバーにのみ接続できます。

  • Unknown - SecureSocket オブジェクトではまだ証明書を検証していません。 connect() を呼び出す前と connect イベントまたは ioError イベントのいずれかが送出される前は、 serverCertificateStatus プロパティにはこの状態が設定されています。

  • Untrusted signers - 証明書には、クライアントコンピューターの信頼ストアに格納されている信頼されたルート証明書への「チェーン」がありません。

SecureSocket オブジェクトと通信する場合は、セキュアなプロトコルおよび有効で信頼された証明書が使用されているサーバーが必要です。その他の点では、SecureSocket オブジェクトと Socket オブジェクトの使用方法は同じです。

SecureSocket オブジェクトは一部のプラットフォームではサポートされていません。SecureSocket クラスの isSupported プロパティを使用すると、ランタイムが現在のクライアントコンピューターで SecureSocket オブジェクトの使用をサポートしているかどうかを確認できます。

詳しくは、以下を参照してください。

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.connect() メソッドでは、1024 以上の TCP ポート番号にしか接続できません。この制限により、 XMLSocket オブジェクトと通信するサーバーデーモンにも、1024 以上のポート番号を割り当てる必要があります。1024 未満のポート番号は、FTP(21)、Telnet(23)、SMTP(25)、HTTP(80)、POP3(110)などのシステムサービスによって使用されることが多いため、XMLSocket オブジェクトはセキュリティ上の理由からこれらのポートにアクセスできません。こうしたリソースが不適切な方法でアクセスされたり悪用されたりする可能性を小さくするために、ポート番号が制限されています。

  • アプリケーションセキュリティサンドボックスの外部にあるコンテンツの場合、 XMLSocket.connect() メソッドでは、コンテンツが存在するドメイン内のコンピューターにしか接続できません(この制限は、 URLLoader.load() のセキュリティ規則と同じです)。コンテンツが存在するドメイン以外で実行されるサーバーデーモンに接続するには、特定のドメインからのアクセスを許可するクロスドメインポリシーファイルを作成します。クロスドメインポリシーファイルについて詳しくは、 AIR のセキュリティ を参照してください。

注意: XMLSocket オブジェクトと通信できるようにサーバーを設定することは、場合によっては困難が伴います。リアルタイムのインタラクティブ機能を必要としないアプリケーションでは、XMLSocket クラスではなく URLLoader クラスを使用してください。

XMLSocket クラスの XMLSocket.connect() メソッドと XMLSocket.send() メソッドを使用すると、ソケット接続を介してサーバーとの間で XML を転送できます。 XMLSocket.connect() メソッドは、Web サーバーのポートに対してソケット接続を確立します。 XMLSocket.send() メソッドは、ソケット接続で指定されたサーバーに XML オブジェクトを渡します。

XMLSocket.connect() メソッドを呼び出すと、アプリケーションによってサーバーへの TCP/IP 接続が開かれ、次のいずれかのイベントが発生するまでその接続が開いたまま維持されます。

  • XMLSocket クラスの XMLSocket.close() メソッドが呼び出される。

  • XMLSocket オブジェクトへの参照が 1 つも存在しなくなる。

  • 接続が切れる(モデムの切断など)。

XMLSocket クラスによるサーバーへの接続

ソケット接続を確立するには、ソケット接続の要求を受け付けて Flash Player または AIR アプリケーションに応答を送るサーバーサイドアプリケーションを作成する必要があります。このようなサーバーサイドアプリケーションは、AIR または Java、Python、Perl などの別のプログラミング言語で作成できます。XMLSocket クラスを使用するには、サーバーコンピューターは XMLSocket クラスで使用されるシンプルプロトコルに対応したデーモンを実行する必要があります。

  • XML メッセージは、全二重 TCP/IP ストリームソケット接続を介して送られます。

  • 個々の XML メッセージは完全な XML ドキュメントであり、ゼロ(0)バイトで終了します。

  • 1 つの XMLSocket 接続を使用して送受信できる XML メッセージの数に制限はありません。

サーバーソケット

ServerSocket クラスを使用すると、他のプロセスが伝送制御プロトコル(TCP)ソケットを使用してアプリケーションに接続できます。接続しているプロセスは、ローカルコンピューターまたはネットワークに接続された別のコンピューター上で動作できます。ServerSocket オブジェクトが接続要求を受信すると、 connect イベントが送出されます。このイベントを伴って送出された ServerSocketConnectEvent オブジェクトには Socket オブジェクトが含まれています。それ以降は、この Socket オブジェクトを使用して他のプロセスと通信できます。

受信ソケット接続を監視するには:

  1. ServerSocket オブジェクトを作成して、ローカルポートにバインドします。

  2. connect イベントに対するイベントリスナーを追加します。

  3. listen() メソッドを呼び出します。

  4. connect イベントに応答して、各受信接続に Socket オブジェクトを提供します。

ServerSocket オブジェクトは close() メソッドが呼び出されるまで、新しい接続を継続的に監視します。

次のコード例では、ソケットサーバーアプリケーションの作成方法を示します。この例では、ポート 8087 で受信接続を監視します。接続を受信すると、メッセージ(「Connected」という文字列)がクライアントソケットに送信されます。これ以降、サーバーで受信したメッセージはすべてクライアントにエコーバックされます。

<html> 
<head> 
<script src="AIRAliases.js"></script> 
<script language="javascript"> 
        var serverSocket; 
        var clientSockets = new Array(); 
        function startServer() 
        { 
            try 
            { 
                // Create the server socket 
                serverSocket = new air.ServerSocket(); 
                 
                // Add the event listener 
                serverSocket.addEventListener( air.Event.CONNECT, connectHandler ); 
                serverSocket.addEventListener( air.Event.CLOSE, onClose ); 
                 
                // Bind to local port 8087 
                serverSocket.bind( 8087, "127.0.0.1" ); 
                 
                // Listen for connections 
                serverSocket.listen(); 
                air.trace( "Listening on " + serverSocket.localPort ); 
            } 
            catch( e ) 
            { 
                air.trace( e ); 
            } 
        } 
        function connectHandler( event ) 
        { 
            //The socket is provided by the event object 
            var socket = event.socket; 
            clientSockets.push( socket ); 
             
            socket.addEventListener( air.ProgressEvent.SOCKET_DATA, socketDataHandler); 
            socket.addEventListener( air.Event.CLOSE, onClientClose ); 
            socket.addEventListener( air.IOErrorEvent.IO_ERROR, onIOError ); 
             
            //Send a connect message 
            socket.writeUTFBytes("Connected."); 
            socket.flush(); 
             
            air.trace( "Sending connect message" ); 
        } 
         
        function socketDataHandler( event ) 
        { 
            var socket = event.target 
                 
            //Read the message from the socket 
            var message = socket.readUTFBytes( socket.bytesAvailable ); 
            air.trace( "Received: " + message); 
            // Echo the received message back to the sender 
            message = "Echo -- " + message; 
            socket.writeUTFBytes( message ); 
            socket.flush(); 
            air.trace( "Sending: " + message ); 
        } 
         
        function onClientClose( event ) 
        { 
            air.trace( "Connection to client closed." ); 
            //Should also remove from clientSockets array... 
        } 
        function onIOError( errorEvent ) 
        { 
            air.trace( "IOError: " + errorEvent.text ); 
        } 
        function onClose( event ) 
        { 
            air.trace( "Server socket closed by OS." ); 
        } 
</script> 
</head> 
<body onload="startServer()"> 
</body> 
</html>

詳しくは、以下を参照してください。

UDP ソケット(AIR)

ユニバーサルデータグラムプロトコル(UDP)は、ステートレスネットワーク接続経由でメッセージを交換する手段です。UDP では、メッセージの配信順序またはメッセージの配信自体が保証されません。UDP を使用すると、通常、オペレーティングシステムのネットワークコードでは、メッセージのマーシャリング、追跡および応答にかかる時間が短縮されます。したがって、一般的に、UDP メッセージが送信先のアプリケーションに到着するまでの遅延時間は TCP メッセージよりも短くなります。

UDP ソケット通信は、ゲームでの位置の更新や音声チャットアプリケーションの音声パケットなど、リアルタイムな情報を送信する必要がある場合に役に立ちます。このようなアプリケーションでは、ある程度のデータ損失は許容されるので、受信が保証されるよりも伝送待ち時間が短縮される方が重要です。その他の場合は、ほとんどすべての用途に TCP ソケットの方が適しています。

AIR アプリケーションでは、DatagramSocket クラスおよび DatagramSocketDataEvent クラスを使用して、UDP メッセージを送受信できます。UDP メッセージを送受信するには:

  1. DatagramSocket オブジェクトを作成します。

  2. data イベントに対するイベントリスナーを追加します。

  3. bind() メソッドを使用して、ソケットを IP アドレスとポートにバインドします。

  4. send() メソッドを呼び出し、送信先コンピューターの IP アドレスとポートを渡してメッセージを送信します。

  5. data イベントに応答してメッセージを受信します。このイベントに対して送出された DatagramSocketDataEvent オブジェクトには、メッセージデータが格納された ByteArray オブジェクトが含まれています。

次のコード例では、アプリケーションで UDP メッセージを送受信する方法を示します。この例では、文字列「Hello」を含む単一メッセージを送信先コンピューターに送信します。また、すべての受信メッセージをトレースします。

<html> 
<head> 
<script src="AIRAliases.js"></script> 
<script language="javascript"> 
    var datagramSocket; 
     
    //The IP and port for this computer 
    var localIP = "192.168.0.1"; 
    var localPort = 55555; 
     
    //The IP and port for the target computer 
    var targetIP = "192.168.0.2"; 
    var targetPort = 55555; 
     
    function createDatagramSocket() 
    { 
        //Create the socket 
        datagramSocket = new air.DatagramSocket(); 
        datagramSocket.addEventListener( air.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 = new air.ByteArray(); 
        data.writeUTFBytes("Hello."); 
         
        //Send the datagram message 
        datagramSocket.send( data, 0, 0, targetIP, targetPort); 
    } 
     
    function dataReceived( event ) 
    { 
        //Read the data from the datagram 
        air.trace("Received from " + event.srcAddress + ":" + event.srcPort + "> " + 
            event.data.readUTFBytes( event.data.bytesAvailable ) ); 
    } 
</script> 
</head> 
<body onload="createDatagramSocket()"> 
</body> 
</html>

UDP ソケットを使用する場合は、以下の事項を考慮してください。

  • 単一パケットのデータは、送信者と受信者との間にあるすべてのネットワークノードまたはネットワークインターフェイスの最大転送ユニット(MTU)の最小値を超えることはできません。send() メソッドに渡される ByteArray オブジェクトのデータはすべて単一パケットとして送信されます(TCP では、サイズの大きいメッセージは複数のパケットに分割されます)。

  • 送信元と送信先との間にハンドシェイクは確立されません。送信先が存在しないか、指定されたポートにアクティブなリスナーが設定されていない場合、メッセージは破棄され、エラーは通知されません。

  • connect() メソッドを使用する場合、他の送信元から送信されたメッセージは無視されます。UDP 接続では、簡易的なパケットフィルタリング機能しか提供されません。ただし、送信先アドレスとポートで必ずしも監視プロセスが有効になっているわけではありません。

  • UDP トラフィックによってネットワークが圧迫される可能性があります。ネットワークで輻輳が発生する場合、ネットワーク管理者はサービス品質の管理機能を実装する必要があります(TCP にはビルトインのトラフィック管理機能があり、ネットワークでの輻輳による影響を軽減できます)。

詳しくは、以下を参照してください。

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 アドレスの長い形式の文字列が返されます。

  • IP 値には二重コロンの省略形は含まれません。

  • 16 進数は小文字のみです。

  • IPv6 アドレスは角括弧([])で囲まれています。

  • アドレスの各 4 桁は 0~4 桁の 16 進数として出力され、先頭のゼロは省略されます。

  • アドレスの各 4 桁がすべてゼロの場合は、以下に示す例外を除いて、二重コロンではなく、1 個のゼロとして出力されます。

Flash Player で返される IPv6 の値には、以下の例外があります。

  • 不明な IPv6 アドレス(すべてゼロ)は [::] として出力されます。

  • ループバックまたは localhost の IPv6 アドレスは [::1] として出力されます。

  • IPv4 のマップされた(IPv6 に変換された)アドレスは [::ffff:a.b.c.d] として出力されます。a.b.c.d は、一般的な IPv4 のドット付き 10 進表記の値です。

  • IPv4 と互換性のあるアドレスは [::a.b.c.d] として出力されます。a.b.c.d は、一般的な IPv4 のドット付き 10 進表記の値です。