In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

flash on 2013-8-28

ソケット通信のサンプル
@author Hikipuro
Get Adobe Flash player
by hayami_susumu 28 Aug 2013
    Embed
/**
 * Copyright hayami_susumu ( http://wonderfl.net/user/hayami_susumu )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/AeBv
 */

package 
{
    import flash.display.ActionScriptVersion;
    import flash.display.Graphics;
    import flash.display.SimpleButton;
    import flash.display.Sprite;
    import flash.errors.IOError;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.events.ProgressEvent;
    import flash.events.SecurityErrorEvent;
    import flash.net.Socket;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFieldType;
    import flash.ui.Keyboard;
    import flash.utils.ByteArray;
    import flash.utils.Endian;
    import flash.system.Security;
    import flash.system.SecurityPanel;
    
    /**
     * ソケット通信のサンプル
     * @author Hikipuro
     */
    public class Main extends Sprite 
    {
        /**
         * 接続先サーバ名
         */
        private const server:String = "hiroshi.dnip.net";
        
        /**
         * 接続先ポート
         */
        private const port:int = 3200;
        
        /**
         * セキュリティポリシーファイルを取得するポート
         */
        private const policyPort:int = 3210;
        
        /**
         * 図形描画用スプライト
         */
        private var sprite:Sprite;
        
        /**
         * 結果表示用テキストフィールド
         */
        private var textField:TextField;
        
        /**
         * テキスト入力欄
         */
        private var textInput:TextField;
        
        /**
         * ボタン
         */
        private var button1:SimpleButton;  
       
        /**
         * ボタンのラベル
         */
        private var buttonText1:TextField;
        
        /**
         * ソケットオブジェクト
         */
        private var socket:Socket;
        
        /**
         * ソケットで受信したデータのタイプ
         */
        private var packetType:int = 0;
        
        /**
         * 文字列を受信した時の文字列長さ
         */
        private var stringSize:int = 0;
        
        /**
         * 文字列サイズ受信済みフラグ
         */
        private var stringSizeReaded:Boolean = false;
        
        // --------------------------------------------------------------------
        
        /**
         * コンストラクタ
         */
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        /**
         * 初期化イベント
         * @param    e
         */
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
            
            // ポリシーファイルを取得する
            // Flash Player 9 以降? では、ポリシーファイルを xmlsocket:// で取得しないと
            // ソケット通信が開始できないようになったそうです。
            // http:// で、crossdomain.xml を取得するだけでは
            // ソケット通信が許可できないようになっています。
            // これは、同一ドメイン内のソケットに接続する場合でも必要になります。
            Security.loadPolicyFile("xmlsocket://" + server + ":" + policyPort);

            // テキスト入力欄の作成
            textInput = new TextField();
            textInput.type = TextFieldType.INPUT;
            textInput.x = 10;
            textInput.y = 210;
            textInput.width = 230;
            textInput.height = 20;
            textInput.border = true;
            textInput.borderColor = 0xcccccc;
            textInput.addEventListener(KeyboardEvent.KEY_DOWN, onTextInputKeyDown);
            addChild(textInput);
            
            // ボタンのラベルの作成
            buttonText1 = new TextField();
            buttonText1.autoSize = TextFieldAutoSize.CENTER;
            buttonText1.selectable = false;
            buttonText1.x = 278;
            buttonText1.y = 210;
            buttonText1.text = "送信";
            addChild(buttonText1);
            
            // ボタンの作成
            button1 = new SimpleButton();
            button1.x = 250;
            button1.y = 210;
            button1.upState = makeRoundRect(0xDDDDDD, 60, 20, 10);
            button1.overState = makeRoundRect(0xFFFFFF, 60, 20, 10);
            button1.downState = makeRoundRect(0xBBBBBB, 60, 20, 10);
            button1.hitTestState = button1.upState;
            button1.addEventListener(MouseEvent.MOUSE_DOWN, onButtonMouseDown);
            addChild(button1);
            
            // 結果表示用テキストフィールドの準備
            textField = new TextField();
            textField.wordWrap = true;
            textField.x = 0;
            textField.y = 0;
            textField.width = 320;
            textField.height = 200;
            textField.border = true;
            textField.borderColor = 0xcccccc;
            addChild(textField);
            
            // 図形描画領域の準備
            sprite = new Sprite();
            sprite.x = 320;
            addChild(sprite);
            
            // ソケットオブジェクトを作成
            socket = new Socket();
            
            // イベントハンドラ登録
            socket.addEventListener(Event.CONNECT, connectHandler);
            socket.addEventListener(Event.CLOSE, closeHandler);
            socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
            socket.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
            socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
            
            // データの並び順を設定
            // .net のサーバはリトルエンディアンでデータを扱うので、
            // サーバに合わせてリトルエンディアンに設定
            socket.endian = Endian.LITTLE_ENDIAN;
            
            // セキュリティサンドボックスタイプの表示
            appendText("セキュリティサンドボックスタイプ : " + Security.sandboxType);
            
            // サーバに接続
            try {
                appendText("接続を開始します。");
                socket.connect(server, port);
            }
            catch (e:Error)
            {
                appendText("socket.connect() で例外が発生しました。");
                appendText(e.toString());
            }
        }
        
        /**
         * テキストフィールドに文字列を追加
         */
        private function appendText(text:String):void
        {
            textField.appendText(text + "\n");
            textField.scrollV = textField.maxScrollV;
        }
        
        /**
         * サーバに、テキスト入力欄のメッセージを送信
         */
        private function sendTextMessage():void 
        {
            // 何も入力されてない時はそのまま終了
            if (textInput.text == "")
                return;
                
            // 未接続の場合はそのまま終了
            if (socket.connected == false)
                return;
            
            // 入力欄の文字列を ByteArray に入れる
            var byteArray:ByteArray = new ByteArray();
            byteArray.writeUTFBytes(textInput.text);
            byteArray.position = 0;
            
            // 入力されたメッセージをサーバに送信
            var string:String = byteArray.readUTFBytes(byteArray.length);
            socket.writeByte(2);
            socket.writeInt(byteArray.length);
            socket.writeUTFBytes(string);
            socket.flush();
            
            // 入力欄クリア
            textInput.text = "";
        }
        
        /**
         * 角丸の図形を描いたスプライトを作って返す
         * @param    color    色
         * @param    width    幅
         * @param    height    高さ
         * @param    round    角丸の大きさ
         * @return    スプライト
         */
        private function makeRoundRect(color:uint, width:int, height:int, round:int):Sprite
        {
            var s:Sprite = new Sprite();
            s.graphics.lineStyle(2);
            s.graphics.beginFill(color);
            s.graphics.drawRoundRect(0, 0, width, height, round);
            s.graphics.endFill();
            s.alpha = 0.3;
            return s;
        }
        
        // --------------------------------------------------------------------
        
        /**
         * テキスト入力欄でキーが押された時のイベント
         * @param    event
         */
        private function onTextInputKeyDown(event:KeyboardEvent):void
        {
            if (event.keyCode == Keyboard.ENTER)
                sendTextMessage();
        }

        /**
         * 送信ボタンが押された時のイベント
         * @param    event
         */
        private function onButtonMouseDown(event:MouseEvent):void
        {
            sendTextMessage();
        }
        
        /**
         * サーバに接続された時のイベント
         * @param    event
         */
        private function connectHandler(event:Event):void
        {
            appendText("サーバに接続しました。");
        }
        
        /**
         * ソケットが閉じられた時のイベント
         * @param    event
         */
        private function closeHandler(event:Event):void
        {
            appendText("接続が閉じられました。");
        }

        /**
         * データ受信イベント
         * @param    event
         */
        private function socketDataHandler(event:ProgressEvent):void
        {
            var stopFlag:Boolean = false;
            
            // データが 1 バイトでも残っている時はループ
            while (socket.bytesAvailable > 0)
            {
                // データのタイプをチェック
                if (packetType == 0)
                    packetType = socket.readByte();
                
                // タイプごとに処理方法を変える
                switch (packetType) 
                {
                    // 1 番は、テキスト受信メッセージ
                    case 1:
                        stopFlag = onRecieveType1Packet();
                        break;
                    // 2 番は、図形描画メッセージ
                    case 2:
                        stopFlag = onRecieveType2Packet();
                        break;
                }
                
                // メッセージ受信終了の場合はループを抜ける
                if (stopFlag)
                    break;
            }        
            //trace("bytesAvailable : " + socket.bytesAvailable);
        }
        
        /**
         * IO エラーイベント
         * @param    event
         */
        private function ioErrorHandler(event:IOErrorEvent):void
        {
            trace("ioErrorHandler: " + event);
            appendText("サーバに接続できませんでした。");
        }
        
        /**
         * セキュリティエラーイベント
         * @param    event
         */
        private function securityErrorHandler(event:SecurityErrorEvent):void
        {
            trace("securityErrorHandler: " + event);
            appendText("セキュリティエラーが発生しました。");
            appendText(event.text);
        }
        
        // --------------------------------------------------------------------
        
        /**
         * テキストメッセージを受信した時
         * @return
         */
        private function onRecieveType1Packet():Boolean
        {
            // 文字数が決定していない時は
            // 文字数を受信する
            if (stringSizeReaded == false)
            {
                // 未受信分のデータが 4 バイトより小さい場合は、そのまま終了
                if (socket.bytesAvailable < 4)
                    return true;
                
                // 文字数受信
                stringSize = socket.readInt();
                stringSizeReaded = true;
            }
            
            // 未受信分のデータのバイト数が文字数より小さい場合は、そのまま終了
            if (socket.bytesAvailable < stringSize)
                return true;
            
            // 指定された文字数分、テキストメッセージを受信
            var str:String = socket.readUTFBytes(stringSize);
            appendText(str);
            stringSizeReaded = false;
            stringSize = 0;
            
            packetType = 0;
            return false;
        }
        
        /**
         * 図形描画メッセージを受け取った時
         * @return
         */
        private function onRecieveType2Packet():Boolean
        {
            // 未受信分のデータが 20 バイトより小さい場合は、そのまま終了
            if (socket.bytesAvailable < 20)
                return true;
            
            // 図形の情報を受信
            var x:int = socket.readInt();
            var y:int = socket.readInt();
            var width:int = socket.readInt();
            var height:int = socket.readInt();
            var color:int = socket.readInt();
            
            // 受信した位置・サイズ・色の図形を描く
            var g:Graphics = sprite.graphics;
            g.beginFill(color, 0.8);
            g.drawRect(x, y, width, height);
            g.endFill();
            
            packetType = 0;
            return false;
        }
    }
    
}