当前位置: 首页 > 图文教程 > Flash动画 > Flash动画制作 > AS3 socket解码设计时忽略的问题

Flash动画制作
巧用超级解霸在Flash V5.0中插入录像
教你用Flash MX来制作简单的课件界面
Flash MX 2004 ActionScript图文教程(二)
Flash MX 2004 ActionScript图文教程(三)
Flash MX 2004 ActionScript图文教程(四)
Flash MX 2004 ActionScript图文教程(五)
Flash MX 2004 ActionScript图文教程(六)
flash场景之间相互跳转的实现方法
Flash本地加密
FLASH -- 关于变量的问题FLASH -- 关于变量的问题
Flash5 画任意直线教程
Flash MX 视频导入功能详解
制作飞舞的蝴蝶
Flash MX 2004 ActionScript图文教程(七)
Flash MX 2004 ActionScript图文教程(八)
Flash MX 2004 ActionScript图文教程(九)
Flash MX 2004 ActionScript图文教程(十)
Flash教程 飞翔的文字
Flash MX 2004 ActionScript图文教程(十一)
制作Flash网站技巧拾零

Flash动画制作 中的 AS3 socket解码设计时忽略的问题


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2010-01-04   浏览: 80 ::
收藏到网摘: n/a

调试游戏确实是一项磨人的工作。难怪很多业内人都喜欢说“好游戏是改出来的”。奇都基础平台目前还在测试,陆陆 续续收到了很多朋友的反馈(想参与测试的朋友欢迎联系我索取激活码)。所以这段时间的主要工作是在做美化和优化,新的竞技系统也在紧锣密鼓的准备中。

  这里主要想说一下socket解码在设计时忽略的一个问题。(感谢Lite3的反馈)。

  对于客户端的Socket的数据基本读取方式一般来说可以分为三种:

1、按照数据流的结尾标记截取
2、按照包头记录的包长度截取
3、按照包长度截取并验证结尾标记。

第一种方式:如图,通常做发是每个包结尾发送一个\0标记,表示这个数据包发送完了。socket每次读取1个字节直到遇到结尾符,结束读取将数据包传递到逻辑层。这种方式在xmlSocket时就已经用了很多了。

第二种方式:如图包头用一个整型记录完整包的长度。每次都先读取一个包长度,然后按照包长度读取指定长度的数据作为一个完整数据包传递到到逻辑层。

第三种方式:如图。这种方式把以上两种方式做了结合,读取的时候无需一个一个字节读,直接读取指定长度。结尾符可以用来做校验判定,同时可以作为包长度字节的读取依据。(如果上一个包有问题可以丢弃之后,以结尾符为标记读取下一个包的包长度。)

  介绍了一点基本原理,下面说一下这个设计缺陷。

问题:

  通讯中我们使用的是第二种方式——包长读取。在通讯类中创建一个临时存储变量_dataArray,提供一个getData():*公用方法,供外部取出数据。每次读完一个完整包后压入_dataArray,同时触发"recievedData"事件。代码如下:

private function socketDataHandler(event:ProgressEvent):void
{
//_readFlag:int;//0表示全部读完了,1表示长度读取完毕 2表示正在读取数据
while (bytesAvailable)
{
     if (_readFlag == 0&&bytesAvailable>=4)
{
       _length = Number(readInt());
       _readFlag=1
}
   if (_readFlag == 1 && bytesAvailable >= _length)
{
      var temp:Object = readObject();
     _dataArray.push(temp);
     dispatchEvent(new Event("recievedData"));//
     _length = 0;
     _readFlag = 0;
}
}
}


  以上代码从结构上看是没有任何问题的,而且在测试前期我们也一直用着没有任何问题。逻辑相当清楚:接收到socket的事件后首先读取一个包长,然后按照包长读取数据。读取完毕发出事件。。。

  那么,问题终于来了——网友Lite3出现了。^ _ ^

  Lite3发来了一个出错提示:
          Error: Error #1502: 脚本的执行时间已经超过了 15 秒的默认超时设置。
          at qdooo.net::mySocket/socketDataHandler()

  相信大家一看就能知道问题出在了哪里——问题就在while上。

       while的循环等待时间因为某种原因超过了15秒。这里所指的某种原因就是网速,那天Lite3那边的网速非常慢。这样一来放大了设计中一处缺陷所照成的影响——必须等到可读数据的长度等于或者大于包长度的时候才开始读取,也就是下面这句:

if (_readFlag == 1 && bytesAvailable >= _length)

正是由于这个判断做了限定,如果数据长度不够,那么他会在while中一直循环等待。直到超过15秒报错。

解决:

  分析好了原因那么就很好解决了,想办法读空流里面的数据让while跳出等待就行了。