3

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");
        }
    }
4

1 に答える 1

0

ソケットからバイト配列にデータを実際に引き出してから、ソケットではなくバイト配列で操作を行う必要があります。ソケットまたは bytearray で read***() メソッドのいずれかを呼び出すときは、read メソッドの値だけ .position プロパティを移動します。これは、readObject で提供されたインデックス エラーが発生する理由でもあります。readObject を呼び出す前に、まず BA の .position プロパティを 0 に設定します。

 ba.position = 0;
 var o:Object = ba.readObject();

あなたの質問に対する私のコメントとこの回答の詳細は、少なくともあなたのコードの根本的な問題だと思います。これを簡単に理解できるように、送信ソケットのコードも投稿する必要があります。

于 2012-04-29T06:32:41.833 に答える