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

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



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


  1. /**  
  2.  
  3.  * @(#)NetBottomHandle.as  
  4.  
  5.  * @author soda.C  mail:[email protected]  
  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出错等等 希望有兴趣的人继续留贴讨论,呵呵 点击下载此文件

你可能感兴趣的:(网络,socket,function,服务器,Flash,通讯)