1

AS3 Event:ProcessEvent.SOCKET_DATA を使用して、ソケット データをリッスンします。これは、ソケット データ ハンドルの AS3 コードです。

private function packetHandler( e:ProgressEvent ):void
    {
        while( m_socket.bytesAvailable && m_socket.bytesAvailable >= pLen )
        {
            //pLen means the packet length
            //pLen init is zero
            if( pLen == 0 )
            {
                //PACKET_LEN stands for the solid length of one packet
                //PACKET_LEN = HEAD_LEN + 4
                //the 4 means an unsigned int which means the packet content length
                if( m_socket.bytesAvailable > PACKET_LEN )
                {
                    m_socket.readBytes(  headByteBuffer, 0, HEAD_LEN );
                    headByteBuffer.clear();
                    pLen = m_socket.readUnsignedInt() + 4;
                }
                else
                {
                    break;
                }
            }
            //recieved a whole packet now handle it
            else
            {
                var newPacket:ByteArray = new ByteArray();
                
                newPacket.endian = Endian.LITTLE_ENDIAN;
                m_socket.readBytes( newPacket, 0, pLen );
                
                parasMsg( newPacket, pLen-4 );
                pLen = 0;
            }
        }
    }

パケット全体は、次の図で説明できます。 http://wuzhiwei.net/problems/packet.gif

私の問題は次のとおりです。フラッシュで受信された不完全なパケットが1つあり、ハンドルがトリガーされた場合。しかし、パケットの左側の部分がハンドルをトリガーすることはなく、パケットの左側の部分が失われたようです!!!

キャプチャ ツールを使用したところ、tcp パケットは正常であることがわかりましたが、左側の部分でイベントが再度トリガーされないのはなぜですか?

以下の詳細なデバッグ情報を取得できます。ありがとうございました!

これは私のログです:

  • byteava は m_socket の bytesAvailable を意味します

==>sendPacket: {"rangeID":"1","uid":"145962","serviceType":"copyscene","cmd":"CopySceneMoveAsk","pathPoint":[{"col":7, "row":6},{"col":7,"row":5},{"col":7,"row":4},{"col":7,"row":3},{ "col":6,"row":3}],"sn":"79","smallPathPoint":[[22,19],[22,18],[22,17],[22,16] ,[22,15],[22,14],[22,13],[21,13],[21,12],[21,11],[20,11],[20,10]]} 、bytesLoaded = 463

ProgressEvent Triggered!0 socket byteava = 373 evt loaded:373 evt total:0 evt:[ProgressEvent type="socketData" bubble=false cancelable=false eventPhase=2 bytesLoaded=373 bytesTotal=0]

ソケットからパケットを検索、pLen=288 ソケット byteava = 276

ProgressEvent Triggered!288 socket byteava = 441 evt loaded:165 evt total:0 evt:[ProgressEvent type="socketData" bubble=false cancelable=false eventPhase=2 bytesLoaded=165 bytesTotal=0]

バッファへのパケットの読み取りを開始、pLen=288 socket byteava = 441

パケット全体の内容: パケットをバッファに読み込み、pLen=288 ソケット byteava = 153

サーバー パケット コンテンツ バイト バッファー ava:288 len:288 pos: 0

Server Paras Data: data len: 284 data content: {"cmd":"CopySceneMoveNotify","gtcmd":"108","layer":"1","pathPoint":[{"col":7,"row ":6},{"col":7,"row":5},{"col":7,"row":4},{"col":7,"row":3},{"col" ":6,"row":3}],"smallPathPoint":[[22,19],[22,18],[22,17],[22,16],[22,15],[22, 14]、[22,13]、[21,13]、[21,12]、[21,11]、[20,11]、[20,10]HTTP/1.1 200

_[20,10]HTTP/1.1 200_これが間違っていたのです!! 別のパケットのヘッダーを持つ不完全なパケット cat。

TCP 接続のキャプチャは次のとおりです。 http://wuzhiwei.net/problems/captured_pa​​ckets.jpg

この質問の写真を掲載できるように、投票していただければ幸いです。

私の英語はあまり上手ではありません。私の言いたいことを理解していただければ幸いです。ありがとうございました!

4

2 に答える 2

0

この時点でデータを受信すると、ソケットのイベント flash.events.ProgressEvent.SOCKET_DATA が発生し、受信したバイトを取得できます ( .bytesAvailable を確認してください)。メッセージが複数のパッケージに分割されると、各パケットのイベントを受け取ります。あなたの場合、m_socket.bytesAvailable >= pLen をチェックすると、pLen の値が間違っている可能性があります。

メッセージの冒頭でメッセージサイズを送信すると仮定します(この場合、メッセージ全体が受信されたかどうかを確認できます)。この場合、受信したバイトを保持するバッファーとしてクラス メンバー (ByteArray ) が必要です。新しいデータが来ると、新しいバイトをこのメンバーにコピーし、メッセージ全体を受信するかどうかを確認する必要があります。バッファにメッセージ全体が含まれている場合は、メッセージを削除してください。一般に、イベント ハンドラーは次のようになります。

protected function onSocketData( pEvt: Event ): void
{
    try
{
       if ( 0 < pEvt.target.bytesAvailable )
       {
    var byteStream: ByteArray = new ByteArray();            
    pEvt.target.readBytes( byteStream, 0, Socket( pEvt.target ).bytesAvailable );
    // Append readed data to your buffer

    do 
    {
        //Check if you have enough bytes to read whole msg and execute it
                    //do..while because maybe it can be more than one msg in buffer

    }
    while ( null != msgContent );
    }
}
catch ( exc )
{

}

}

于 2013-03-04T14:14:19.613 に答える
0

問題は、パケットのソリッド ヘッダーが原因で発生するはずです。

以下は、パケットの 93 バイトのソリッド ヘッダーです。

private static const HTTP_RESPONSE_CONTENT : String = "HTTP/1.1 200 OK \r\n"
        + "Connection: keep-alive \r\n"
        + "Content-Length: 280 \r\n"
        + "Content-Type: text/html \r\n\r\n";

このヘッダーはすべてのパケットのヘッダーにあり、AS3 はそれを に処理しhttp、 でフローを切断する可能性がありContent-Length: 280ます。したがって、280 バイトの左側の部分が SOCKET_DATA イベントをトリガーすることはありません。

このヘッダーを削除すると、問題ありません。

于 2013-12-30T07:13:21.230 に答える