我遇到了一个奇怪的问题,试图使用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");
}
}
答案 0 :(得分:0)
您应该将数据从套接字中拉出一个字节数组,然后对bytearray而不是套接字进行操作。当您调用套接字上的任何读取***()方法或bytearray时,您将.position属性移动read方法的值。这也是您在readObject上获得提供的索引错误的原因。在调用readObject之前,首先将BA的.position属性设置为0。
ba.position = 0;
var o:Object = ba.readObject();
我对您的问题的评论和此答案中的详细信息我认为至少是您的代码的一个基本问题。您还应该发布发送套接字的代码,以便我们更容易理解这一点。