2013-03-04 58 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