我在尝试使用 ByteArrays 通过 Socket 发送对象和 unsigned int 时遇到了一个奇怪的问题。我正在尝试处理我可能会在多个数据包中接收数据的情况。
这是我的套接字数据处理程序:
protected function handleSocketData(e:ProgressEvent):void{
var s:Socket = e.target as Socket;
trace("pre if " + len + " " + s.bytesAvailable);
if (len == 0 && s.bytesAvailable >= 4) {
len = s.readUnsignedInt();
}
trace(len + " " + s.bytesAvailable);
if (len > 0 && s.bytesAvailable >= len){
var ba:ByteArray = new ByteArray();
//s.readBytes(ba, 0, len);
s.readBytes(ba, 0, s.bytesAvailable); //should be len
//trace("handle socket before inflate " + ba.length);
ba.inflate();
//trace("handle socket after inflate " + ba.length);
var o:Object = ba.readObject();
Overlord.updatePlayers(o);
trace(o.player);
len = 0;
}
}
问题在于s.readBytes(ba, 0, len);
我正在使用 len (在类范围内定义)来处理我可能会收到多个数据包的情况。现在这似乎在我第一次通过套接字获取数据时起作用。
pre if 0 44 - trace I'm getting before the first if statement
38 40 - trace I'm getting after
frank - Everything comes in fine, working!
现在,如果我再次通过套接字发送数据:
**first send:**
pre if 0 44
38 40
frank - working, yay!
**things start to fail every send after:**
pre if 0 46
218759168 42
pre if 218759168 84
218759168 84
pre if 218759168 127
218759168 127
现在看来 readBytes 将数据留在缓冲区中。
奇怪的是,当我换掉s.readBytes(ba, 0, len);
一切s.readBytes(ba, 0, s.bytesAvailable);
似乎都有效时:
使用 s.readBytes(ba, 0, s.bytesAvailable);
**first send**
pre if 0 44
38 40
frank
**everything seems to work after, no old data in the buffer?**
pre if 0 44
38 40
frank
pre if 0 43
37 39
frank
使用的问题bytesAvailable
是现在我无法处理多个数据包。
pre if 2214 2218
2214 2218
RangeError: Error #2006: The supplied index is out of bounds.
at flash.utils::ByteArray/readObject()
我不太确定我在这里缺少什么,似乎只有在我使用 socket.bytesAvailable 时缓冲区才会被清除。有人有意见吗?
编辑
我正在使用这种方法通过套接字发送数据。通过写入 ByteArray 的长度并在数据处理程序中读回它,我试图处理跨多个数据包获取数据对象。
public function sendData(socketData:*):void{
if(_connected){
//trace("sending");
var ba:ByteArray = new ByteArray();
ba.writeObject(socketData);
ba.position = 0;
//trace("byteArray len before send and defalte: " + ba.length)
ba.deflate();
//trace("byteArray len before send and after defalte: " + ba.length)
socket.writeUnsignedInt(ba.length);
socket.writeBytes(ba, 0, ba.length);
socket.flush();
} else {
throw new Error("Socket not open");
}
}