flash - bytesAvailable,readUTF()和ProgressEvent.SOCKET_DATA

标签 flash actionscript-3 sockets

我有一个多人游戏,该游戏从服务器读取XML数据:

 _socket = new Socket();
 _socket.addEventListener(ProgressEvent.SOCKET_DATA, handleTcpData);
.....
private function handleTcpData(event:Event):void {
  while (_socket.bytesAvailable) {
     var str:String = _socket.readUTF();
     updateGUI(str);
  }
}

在大多数情况下,它可以正常工作,但有时用户会提示
游戏为他们而死。他们能够发送命令到
服务器,但从他们的描述中我怀疑,该功能
上面的方法不适用于他们,并且updateGUI()停止调用。

这个问题很难调试...我认为我的服务器(在Perl/C中,
非 fork ,使用poll())效果很好,我必须做点什么
在Flash方面是错误的。

在这里调用readUTF()是个好主意吗?可能是
只有UTF字符串的一部分到达,然后再播放Flash电影
会冻结在readUTF()中,不是吗? (虽然我从未见过)

更新:

是的,谢谢,我需要 catch EOFError,我也有很好的建议
在邮件列表中,我必须阅读_socket.bytesAvailable字节
放入ByteArray并使用该代码(检查我的完整消息是否
到达)-其他不可靠的信息。

因此,我想出了这个办法,但仍然存在一个缺陷:
private function handleTcpData(event:Event):void {
       var len:uint;

       if (0 == _socket.bytesAvailable)
               return;

       try {
               _socket.readBytes(_ba, _ba.bytesAvailable, _socket.bytesAvailable);

               // read the length of the UTF string to follow
               while (_ba.bytesAvailable >= 2) {
                       len = _ba.readUnsignedShort();

                       // invalid length - reset
                       if (0 == len) {
                               trace('XXX invalid len = ' + len);
                               _ba.position = 0;
                               _ba.length = 0;
                               return;
                       }

                       if (_ba.bytesAvailable >= len) {
                               var str:String = _ba.readUTFBytes(len);
                               updateGUI(str);

                               // copy the remaining bytes
                               // (does it work? can it be improved?)
                               var newBA:ByteArray = new ByteArray();
                               newBA.readBytes(_ba);
                               _ba = newBA;
                       }
               }
       } catch(e:Error) {
               trace('XXX ' + e);
               _ba.position = 0;
               _ba.length = 0;
               return;
       }
}

可用字节过多(例如800)时的

  • 而且我的邮件只有400个字节长,然后卡住了。

  • 我也想知道是否可以复制剩余的字节
    改进了(即每次都没有分配新的ByteArray)?

    幸运的是,我经常可以重现此缺陷

    最佳答案

    我想,我找到了解决方案。
    由于TCP性质,可能会出现2种有问题的情况:

    1)几个带有前缀的UTF字符串一次到达
    2)带有前缀的不完整的UTF字符串到来

    此代码应同时处理以下两个方面:

    private function handleTcpData(event:Event):void {
    // CASE 1, JUST KEEP EXTRACTING UTF-STRINGS
     while(_socket.bytesAvailable) {
     try{
       var str:String = _socket.readUTF();
       updateGUI(str);
      }catch(e:Error){
        // CASE 2 INCOMPLETE STRING,
        // WILL BE READ BY LATER handleTcpData CALL
        return;
      }
     }
    }
    

    另外,在我的原始代码中,我以错误的方式复制了ByteArray。我应该:
    var newBA:ByteArray = new ByteArray();
    _ba.readBytes(newBA);
    _ba = newBA;
    

    甚至就地进行而不创建newBA。

    关于flash - bytesAvailable,readUTF()和ProgressEvent.SOCKET_DATA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2318083/

    相关文章:

    actionscript-3 - AS3 使用静态类型调用可能未定义的方法问题

    linux - 刷新 tx udp 套接字内核缓冲区以减少延迟

    java - 创建客户端-服务器应用程序以回显用户发送的内容

    actionscript-3 - 调用函数 vs 调度事件

    actionscript-3 - 为什么转换 Object(null) 不为空?

    flash - Flash Builder 中的输出文件名

    c - 使用 -O 标志编译时套接字代码失败

    actionscript-3 - Flash 中的编译时共享库符号

    Flash AS3 : How to prevent MouseEvent. MOUSE_OUT 当您将鼠标悬停在子 Sprite 上时

    java - 视频培训计划