我有一个多人游戏,该游戏从服务器读取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/