似乎没有触发AS3套接字ProcessEvent.SOCKET_DATA

时间:2013-03-04 14:02:15

标签: actionscript-3 sockets

我们使用AS3事件: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

我的问题是:当Flash中收到一个不完整的数据包并触发了句柄。 但数据包的左侧部分永远不会触发句柄,看起来数据包的左侧部分已丢失!!!

我使用了一个捕获工具,发现tcp数据包没问题,但为什么左边部分没有再次触发事件?

您可以在下面获得更多调试信息。谢谢!

这是我的日志:

  • byteava表示m_socket
  • 的bytesAvailable
  

==> sendPacket:{“rangeID”:“1”,“uid”:“145962”,“serviceType”:“copyscene”,“cmd”:“CopySceneMoveAsk”,“pathPoint”:[{“col “: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 = 463

     

ProgressEvent已触发!0套接字byteava = 373 evt已加载:373 evt total:0 evt:[ProgressEvent type =“socketData”bubbles = false cancelable = false eventPhase = 2 bytesLoaded = 373 bytesTotal = 0]

     

从套接字中查找数据包,pLen = 288 socket byteava = 276

     

ProgressEvent已触发!288套接字byteava = 441 evt已加载:165 evt total:0 evt:[ProgressEvent type =“socketData”bubbles = false cancelable = false eventPhase = 2 bytesLoaded = 165 bytesTotal = 0]

     

开始读取要缓冲的数据包,pLen = 288 socket byteava = 441

     

整个数据包内容:将数据包重命名为缓冲区,pLen = 288 socket byteava = 153

     

服务器数据包内容字节缓冲区ava:288 len:288 pos:0

     

服务器Paras数据:数据len:284数据内容:{“cmd”:“CopySceneMoveNotify”,“gtcmd”:“108”,“layer”:“1”,“pathPoint”:[{“col”:7 , “行”: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_这就是出错了!!带有另一个数据包标题的不完整数据包cat。

以下是TCP连接的捕获: http://wuzhiwei.net/problems/captured_packets.jpg

希望你能投票,以便我可以把这个问题的照片放在上面!

我的英语不是很好,希望你能明白我的意思。 谢谢!

2 个答案:

答案 0 :(得分:0)

Socket的事件flash.events.ProgressEvent.SOCKET_DATA将在您收到数据时触发,您可以获取接收的字节(检查.bytesAvailable)。当msg被拆分为多个包时,您将收到每个数据包的事件。 在你的情况下,当检查m_socket.bytesAvailable> = pLen时,pLen可能有错误的值。

我假设您在消息的请求中发送msg大小(在这种情况下,您可以检查是否收到了整个消息)。在这种情况下,您必须有一个类成员(ByteArray)作为保存接收字节的缓冲区。当新数据到来时,您必须将新字节复制到此成员,而不是检查是否收到整个消息。如果buffer包含整个msg而不是从中删除msg。 通常,您的事件处理程序必须如下所示:

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 )
{

}

}

答案 1 :(得分: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事件。

当我删除此标题时,现在就可以了。