Flash Socket底層接受資料的初級處理

來源:互聯網
上載者:User

用flash
去開發
應用
,,免不了網路通訊,特別是網路遊戲
,需要用到即使通訊。
as3
提供了兩個支援即時通訊的類:XML
Socket
和Socket,前者其實是只支援發送字串,而後者就強大多了,支援發送位元組,相對來說比較底層,而這也給我們更多的發揮空間。
其實,flash socket的網路底層接受資料
,就以與C++伺服器通訊為例子,C++伺服器一般會發一段一段資料過來,每段資料都是由一定結構組成的,一般是訊息頭和訊息頭,然後再逐步分層解析。
在這裡,我只說接受網路底層的處理,一般一段資料前面,還有有一個4個位元組左右的資料,表示的是後面網路流裡的資料有多少....
看下簡單

下載

(21 KB)
資料包2008-6-29 11:52


我們網路底層需要做的處理,就是根據頭4個位元組判斷出後面的資料大小,然後把那一整塊取出來,拋給上層解析,然後又在不停地偵聽,
收到指定大小之後,又做類似的操作,下面看詳細的代碼


/**
 * @(#)NetBottomHandle.as
 * @author soda.C  mail:sujun10@21cn.com
 * @version  1.0
 *
Copyright (C), 2008 soda.C
 *
This program is protected by copyright laws.
 *
Program Name:GameHall
 * @data 2008-3-20
 */
package org.sujun.net
{
        import flash.net.Socket;
        import flash.events.ProgressEvent;
        import flash.utils.ByteArray;
        /**
         * socket資料流裡的底層處理,從這裡接受到伺服器的資料,滿足條件後就會拋出需要的位元組
         * 對資料流的資料,不做任何處理
         *
         * @author soda.C
         */
        public class NetBottomHandle
        {
                private var socket                :Socket;               
                private var listener        :Function;                //接受網路解析出來的資料
                private var msgLen                :int;                        //訊息長度
                private var msgLenMax        :int;                        //收到的訊息最大長度
                private var headLen                :int;                        //訊息頭長度
                private var isReadHead        :Boolean;                //是否已經讀了訊息頭
                private var bytes                :ByteArray;                //所讀資料的緩衝資料,讀出的資料放在這裡
               
                public function NetBottomHandle()
                {
                        msgLenMax = 5000;        //5000位元組
                        headLen = 4;                //4個位元組
                        bytes = new ByteArray();
                        isReadHead = true;
                }
                /**
                 * 設定一個網路通訊執行個體
                 */ 
                public function setSocket(socket:Socket):void
                {
                        this.socket = socket;
                        //監聽......
                        socket.addEventListener(ProgressEvent.SOCKET_DATA, onServerData,false,0,true);
                       
                       
                }
                /**
                 * 接受在網路層裡收到的未經處理資料,傳遞過來的資料為描述長度,以及ByteArray對象functon(len,bytes)
                 * @param listener:接受資料函數
                 */
                public function receiverNetData(listener:Function):void
                {
                        this.listener = listener;
                }
                /**
                 * 伺服器發送過來的資料都在這裡接收,最底層的
                 */
                private function onServerData(event:ProgressEvent):void
                {
                        //一有收到資料的事件,就通過這個函數進行檢驗
                        parseNetData();
                }
                /**
                 * 解析網路資料流
                 */
                private function parseNetData():void
                {
                        //如果需要讀資訊頭
                        if(isReadHead)
                        {
                                if(socket.bytesAvailable >= headLen)
                                {
                                        //讀出指示後面的資料有多大
                                        msgLen = socket.readUnsignedInt();
                                        isReadHead = false;
                                }
                        }
                        //如果已經讀了資訊頭,則看能不能收到滿足條件的位元組數
                        if(!isReadHead && msgLen <= msgLenMax)
                        {
                                //如果為0,表示收到異常訊息
                                if(msgLen == 0)
                                {
                                        //一般訊息長度為0的話,表示與伺服器出了錯,或者即將被斷開等,通知用戶端,進行特別處理
                                        listener(msgLen,null);
                                        return ;
                                }
                                //資料流裡的資料滿足條件,開始讀資料
                                if(socket.bytesAvailable >= msgLen)
                                {
                                        //指標迴歸
                                        bytes.position = 0;
                                        //取出指定長度的網路位元組
                                        socket.readBytes(bytes, 0, msgLen);
                                        listener(msgLen,bytes);
                                        isReadHead = true;
                                }
                        }
                        //如果資料流裡還滿足讀取資料條件,繼續讀取資料
                        if(socket.bytesAvailable >= headLen)
                        {
                                parseNetData();
                        }
                }
        }
}


代碼我就不詳細解說了,注釋得很清楚,這段代碼也是經過我寫過幾個版本錘鍊過的。呵呵
在實際應用中,表現也是比較穩定的
當然,這是比較早期的了,以後再正正應用中,可能還需要做更多的處理,例如每個網路位元組的緩衝,緩衝等,以免過多位元組造成socket出錯等等
希望有興趣的人繼續留貼討論,呵呵
NetBottomHandle.rar


(1.51 KB)

例子代碼
下載次數: 2062008-6-29 11:52

下載消耗 銀子 1 兩 


修改了下代碼的錯誤之後,如果要看詳細的,整個流程,包括服務端的代碼的話,請看這邊文章吧
http://www.sujun.org/article.asp?id=51

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.