2013-03-04 62 views
1

我們使用AS3 Event:ProcessEvent.SOCKET_DATA來偵聽套接字數據。 所以這是我的套接字數據句柄的AS3代碼。AS3 Socket ProcessEvent.SOCKET_DATA似乎未觸發

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

我的問題是:當有閃光收到一個不完整的數據包並觸發手柄。 但是數據包的左側部分永遠不會觸發句柄,而且看起來數據包的左側部分已經丟失!

我用了一個捕獲工具,發現tcp數據包沒問題,但是爲什麼左邊的部分不再觸發事件呢?

您可以在下面獲得更多調試信息。謝謝!

這是我的日誌:

  • byteava裝置m_socket的信息bytesAvailable

==>了sendpacket:{ 「rangeID」: 「1」, 「UID」:「145962 」, 「的serviceType」: 「copyscene」, 「CMD」: 「CopySceneMoveAsk」, 「pathPoint都由」:[{ 「欄」:7, 「行」:6},{ 「欄」:7, 「行」:5} ,{ 「欄」:7, 「行」:4},{ 「欄」:7, 「行」:3},{ 「欄」:6, 「行」: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 = 46 3

ProgressEvent觸發0插座byteava = 373 EVT加載:373 EVT總數:0 EVT:[ProgressEvent類型= 「socketData」 氣泡=假或取消=假的EventPhase = 2的bytesLoaded = 373 BYTESTOTAL = 0]

從socket中找到一個包,pLen = 288 socket byteava = 276

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

開始讀取數據包到緩衝區,pLen = 288 socket byteava = 441

整個數據包內容:Readed分組緩衝,PLEN = 288插座byteava = 153

服務器數據包內容字節緩衝器AVA:288 LEN:288個POS:0

服務器傘兵數據:數據長度: 284數據內容:{「cmd」:「CopySceneMoveNotify」,「gtcmd」:「108」,「layer」:「1」,「pathPoint」:[{「col」:7,「row」:6},{欄 「:7,」 行 「:5},{」 欄 「:7,」 行 「:4},{」 欄 「:7,」 行 「:3},{」 欄 「:6,」 行」 :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_這是哪裏出錯了!不完整的數據包貓與另一個數據包的頭部。

這裏是TCP連接的捕獲: http://wuzhiwei.net/problems/captured_packets.jpg

希望你能投上一票,這樣我可以把我在這個問題上的照片!

我的英文不太好,希望你能明白我的意思。 謝謝!

+0

爲什麼e的類型是ProgressEvent? – 2013-03-04 15:08:16

+0

ProgressEvent.SOCKET_DATA – Tim 2013-03-04 15:36:37

+0

我幾乎可以肯定問題在於packetHandler,特別是在使用時。我的遊戲是服務器/客戶端,通信是通過套接字從來沒有這樣的問題。另外我幾乎如果你改變m_socket.readBytes(newPacket,0,pLen); to m_socket.readBytes(newPacket,0,m_socket.bytesAvailable);你將得到沒有HTTP/1.1的消息200_ – 2013-03-04 15:51:22

回答

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事件。

當我刪除這個頭,它現在沒事了。

0

當您在此時接收到數據時,將觸發Socket事件flash.events.ProgressEvent.SOCKET_DATA,您可以獲取接收到的字節(檢查.bytesAvailable)。當msg被分成多個包時,您將收到每個包的事件。 在你的情況下,當檢查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) 
{ 

} 

}

+0

pLen沒問題。我們可以使用套接字自己的緩衝區來做到這一點。 – Tim 2013-03-04 14:56:00

+0

問題是一個整個數據包的左邊沒有觸發SOCKET_DATA事件。我會盡快告訴你的。 – Tim 2013-03-04 14:57:24