ソケット

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 オブジェクトの使用をサポートしているかどうかを確認できます。

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

TCP ソケットの例:Telnet クライアントの構築

この Telnet の例では、Socket クラスを使用してリモートサーバーに接続し、データを伝送する手法を示します。 この例は、次の手法を示します。

  • Socket クラスを使用したカスタム Telnet クライアントの作成

  • ByteArray オブジェクトを使用したリモートサーバーへのテキストの送信

  • リモートサーバーから受信したデータの処理

このサンプルのアプリケーションのファイルを入手するには、 www.adobe.com/go/learn_programmingAS3samples_flash_jp を参照してください。 Telnet アプリケーションのファイルは、Samples/Telnet フォルダーにあります。 このアプリケーションは次のファイルで構成されています。

ファイル

説明

TelnetSocket.fla

または

TelnetSocket.mxml

Flex(MXML)または Flash(FLA)のユーザーインターフェイスを構成するメインアプリケーションファイル。

TelnetSocket.as

ユーザーインターフェイスロジックを提供するドキュメントクラス(Flash 専用)。

com/example/programmingas3/Telnet/Telnet.as

リモートサーバーへの接続、データの送受信と表示など、アプリケーションに 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.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 つも存在しなくなる。

  • Flash Player が終了する。

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

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

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

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

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

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

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 サーバーのルートディレクトリに置く必要はありません。

ファイルを置いた場所が Java クラスパスに含まれていないためにサーバーを起動できない場合は、「 java -classpath . SimpleServer 」と入力すると、起動できることがあります。

アプリケーションから 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 エラーがスローされます。

XML ソケットサーバーに送信する個々のメッセージには、末尾に終端の改行文字( ¥n )を付ける必要があります。

詳しくは、「 XMLSocket 」を参照してください。

サーバーソケット

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

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

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

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

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

  4. connect イベントに応答して、各受信接続に 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 メッセージを送受信するには:

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

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

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

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

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

次のコード例では、アプリケーションで 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 ソケットを使用する場合は、以下の事項を考慮してください。

  • 単一パケットのデータは、送信者と受信者との間にあるすべてのネットワークノードまたはネットワークインターフェイスの最大転送ユニット(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 進表記の値です。