2012-04-26 8 views
3

ByteArraysを使用してSocket上でオブジェクトとunsigned intを送信しようとすると、奇妙な問題が発生しています。私は複数のパケットでデータを受け取るケースを処理しようとしています。socket.readBytesポインタを移動しない

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; 


     } 
} 

問題は、私は複数のパケットを取得することがケースを処理するために(クラスのスコープで定義された)のlenを使用していs.readBytes(ba, 0, 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! 

は今、私は再びソケットを介してデータを送信する場合:readBytesがバッファ内のデータを残しているよう

**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 

は、今ではそうです。

奇妙な部分は、私はすべてが動作しているよう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を使用しての問題は、今私は複数のパケットを扱うことができないということです。私はsocket.bytesAvailableを使用する場合、バッファのみをクリアなっているよう

pre if 2214 2218 
2214 2218 
RangeError: Error #2006: The supplied index is out of bounds. 
at flash.utils::ByteArray/readObject() 

私は私がここに欠けているものを、非常にわからないんだけど、それはそうです。誰でも入力がありますか?私はソケットを介してデータを送信するため、この方法を使用してい

編集

。 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

バイト配列の長さをlen = s.readUnsignedInt()として設定する目的を明確にすることはできますか? –

+0

@AscensionSystems私は、複数のパケットにオブジェクトを戻す可能性を処理するために、パケットにByteAArrayの長さを付加しています。 – francis

+0

OK更新された回答を後でチェックアウトする必要があります。一晩中自分のプロジェクトで作業していますので、寝る時間です。笑申し訳ありません –

答えて

0

あなたは本当にバイト配列にソケットからデータを取得し、その後のByteArrayではなくソケットにあなたの操作を行う必要があります。ソケットまたはbytearrayの***()メソッドのどれかを呼び出すと、.positionプロパティをreadメソッドの値で移動します。これが、readObjectで指定されたインデックスエラーを取得している理由です。 readObjectを呼び出す前に、まずBAの.positionプロパティを0に設定します。

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

私のあなたの質問にコメントと私は信じてこの答えでは詳細はあなたのコードで非常に少なくとも基本的な問題です。また、送信ソケットのコードを投稿して、これを簡単に把握できるようにする必要があります。

+0

しかし、私が問題を抱えているように見えるのは、複数のパケットにまたがってオブジェクトを取得したときだけです。コードは単一のパケットのために働くようです。私はソケット上でデータを送信するためのコードで私の質問を更新しました – francis

+0

baに 'position'を設定していないというのは実際には問題ではありません。 [inflateの呼び出し後... positionプロパティは0に設定されています。](http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/ByteArray.html#inflate%28 %29)しかし、一般的に、私は同意する、明示的に位置を設定する方が安全だ。 –

関連する問題