ByteArrays を使用してソケット経由でオブジェクトと 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");
}
}