现在的位置: 首页 > 综合 > 正文

Flash Socket 底层接受数据的初级处理(as3.0)

2012年12月21日 ⁄ 综合 ⁄ 共 5624字 ⁄ 字号 评论关闭

用flash去开发应用,,免不了网络通讯,特别是网络游戏,需要用到即使通讯。
as3提供了两个支持即时通讯的类:XMLSocket和Socket,前者其实是只支持发送字符串,而后者就强大多了,支持发送字节,相对来说比较底
层,而这也给我们更多的发挥空间。
其实,flash socket的网络底层接受数据,就以与C++服务器通讯为例子,C++服务器一般会发一段一段数据过来,每段数据都是由一定结构组成
的,一般是消息头和消息头,然后再逐步分层解析。
在这里,我只说接受网络底层的处理,一般一段数据前面,还有有一个4个字节左右的数据,表示的是后面网络流里的数据有多少.... 看下简单示意图


我们网络底层需要做的处理,就是根据头4个字节判断出后面的数据大小,然后把那一整块取出来,抛给上层解析,然后又在不停地侦听,收到指定大小之后,又做类似的操作,下面看详细的代码



  1. /**
     
  2.  
  3.  * @(#)NetBottomHandle.as
     
  4.  
  5.  * @author soda.C  mail:sujun10@21cn.com
     
  6.  
  7.  * @version  1.0
     
  8.  
  9.  * <br>Copyright (C), 2007 soda.C
     
  10.  
  11.  * <br>This program is protected by copyright laws.
     
  12.  
  13.  * <br>Program Name:GameHall
     
  14.  
  15.  * @data 2008-3-20
     
  16.  
  17.  */
      
  18.   
  19. package
     org.sujun.net   
  20.   
  21. {  
  22.   
  23.     import
     flash.net.Socket;  
  24.   
  25.     import
     flash.events.ProgressEvent;  
  26.   
  27.     import
     flash.utils.ByteArray;  
  28.   
  29.     /**
     
  30.  
  31.      * socket数据流里的底层处理,从这里接受到服务器的数据,满足条件后就会抛出需要的字节
     
  32.  
  33.      * 对数据流的数据,不做任何处理
     
  34.  
  35.      */
      
  36.   
  37.     public
     class
     NetBottomHandle   
  38.   
  39.     {  
  40.   
  41.         private
     var
     socket        :Socket;          
  42.         private
     var
     listener    :Function;        //接受网络解析出来的数据
      
  43.         private
     var
     msgLen        :int
    ;            //消息长度
      
  44.         private
     var
     msgLenMax    :int
    ;            //收到的消息最大长度
      
  45.         private
     var
     headLen        :int
    ;            //消息头长度
      
  46.         private
     var
     isReadHead    :Boolean;        //是否已经读了消息头
      
  47.         private
     var
     bytes        :ByteArray;        //所读数据的缓冲数据,读出的数据放在这里
      
  48.   
           
  49.         public
     function
     NetBottomHandle()  
  50.   
  51.         {  
  52.             msgLenMax = 5000;    //5000字节
      

     
  53.             headLen = 4;        //4个字节
      

     
  54.             bytes = new
     ByteArray();  

      
                  
     
  55.         }  
  56.   
  57.         /**
     
  58.  
  59.          * 设置一个网络通讯实例
     
  60.  
  61.          */
        
  62.   
  63.         public
     function
     setSocket(socket:Socket):void
      
  64.   
  65.         {  
     
  66.             this
    .socket = socket;  

     
  67.             //监听......
      

     
  68.             socket.addEventListener(ProgressEvent.SOCKET_DATA, onServerData,false
    ,0,true
    );  

      
                  
      
                  
     
  69.         }  
  70.   
  71.         /**
     
  72.  
  73.          * 接受在网络层里收到的原始数据,传递过来的数据为描述长度,以及ByteArray对象functon(len,bytes)
     
  74.  
  75.          * @param listener:接受数据函数
     
  76.  
  77.          */
      
  78.   
  79.         public
     function
     receiverNetData(listener:Function):void
      
  80.   
  81.         {  
     
  82.             this
    .listener = listener;  

     
  83.         }  
  84.   
  85.         /**
     
  86.  
  87.          * 服务器发送过来的数据都在这里接收,最底层的
     
  88.  
  89.          */
      
  90.   
  91.         private
     function
     onServerData(event:ProgressEvent):void
      
  92.   
  93.         {  
     
  94.             //一有收到数据的事件,就通过这个函数进行检验
      

     
  95.             parseNetData();  
     
  96.         }  
  97.   
  98.         /**
     
  99.  
  100.          * 解析网络数据流
     
  101.  
  102.          */
      
  103.   
  104.         private
     function
     parseNetData():void
      
  105.   
  106.         {  
     
  107.             //如果需要读信息头
      

     
  108.             if
    (isReadHead)  

     
  109.             {  
     
  110.                 if
    (socket.bytesAvailable >= headLen)  

     
  111.                 {  
     
  112.                     //读出指示后面的数据有多大
      

     
  113.                     msgLen = socket.readUnsignedInt();  
     
  114.                     isReadHead = false
    ;  

     
  115.                 }  
     
  116.             }  
  117.   
  118.             //如果已经读了信息头,则看能不能收到满足条件的字节数
      
  119.   
  120.             if
    (!isReadHead && msgLen <= msgLenMax)  
  121.   
  122.             {  
     
  123.                 //如果为0,表示收到异常消息
      

     
  124.                 if
    (msgLen == 0)  

     
  125.                 {  
     
  126.                     //一般消息长度为0的话,表示与服务器出了错,或者即将被断开等,通知客户端,进行特别处理
      

     
  127.                     listener(msgLen,null
    );  

     
  128.                     return
     ;  

     
  129.                 }  
  130.   
  131.                 //数据流里的数据满足条件,开始读数据
      

     
  132.                 if
    (socket.bytesAvailable >= msgLen)  

     
  133.                 {  
     
  134.                     //指针回归
      

     
  135.                     bytes.position = 0;  
     
  136.                     //取出指定长度的网络字节
      

     
  137.                     socket.readBytes(bytes, 0, msgLen);  
     
  138.                     listener(msgLen,bytes);  
     
  139.                 }  
     
  140.             }  
  141.   
  142.             isReadHead = false
    ;  
  143.   
  144.             //如果数据流里还满足读取数据条件,继续读取数据
      
  145.   
  146.             if
    (socket.bytesAvailable >= headLen)  
  147.   
  148.             {  
     
  149.                 parseNetData();  
     
  150.             }  
     
  151.         }  
     
  152.     }  
     
  153. }  


代码我就不详细解说了,注释得很清楚,这段代码也是经过我写过几个版本锤炼过的。呵呵 在实际应用中,表现也是比较稳定的
当然,这是比较早期的了,以后再正正应用中,可能还需要做更多的处理,例如每个网络字节的缓冲,缓存等,以免过多字节造成socket出错等等
希望有兴趣的人继续留贴讨论,呵呵 下载文件点击下载此文件

抱歉!评论已关闭.