AS3 TCP Socket 拆包

AS3 TCP Socket 拆包

  • 作者:柳大·Poechant(钟超)
  • 邮箱:zhongchao.ustc#gmail.com(# -> @)
  • 博客:Blog.CSDN.net/Poechant
  • 日期:June 2nd, 2012

在 AS3 中的 Socket 只有 TCP 一种方式,而 TCP 就必然面临拆包的问题。对于 Windows、Linux、Mac等操作系统的不同网络模型,Flash 程序在不拆包下的运行糟糕程度不一样,我的亲身体会是 Windows 的网络模型会积攒更大的缓冲区数据让 Flash TCP Socket 每次收到的数据量都比 Mac 上的多,所以情况就更糟糕。这时候拆包的效果就十分明显。

下面实例中的 _socket 和 lastReservedLength 都是在函数外部定义的,其定义不影响程序的理解。各段含义我写在了程序的注释中。

部分代码如下:


private function onResponse(e:ProgressEvent):void
{
    // Data available from socket
    while (_socket.bytesAvailable > 0)
    {
        var tmpLength:int = 0;
        
        // Last package received is incomplete, and package length maintains last reserved length
        if (lastReservedLength > 0)
        {
            // CASE 1: Package is still incomplete after receiving data from socket at least once
            if (lastReservedLength > _socket.bytesAvailable + 4) break;
                
                // CASE 2: The last part of a package
            else tmpLength = lastReservedLength;
        }
            // Last package received is complete, and package length should be read from socket 
        else
        {
            var lengthBytes:ByteArray = new ByteArray();
            lengthBytes.endian = Endian.LITTLE_ENDIAN;
            
            _socket.readBytes(lengthBytes, 0, 4); // TODO Crash!
            //Error: Error #2030: End of file was encountered.
            //at flash.net::Socket/readBytes()
            
            tmpLength = lengthBytes.readInt();
            
            // CASE 3: The first part of a package
            if (_socket.bytesAvailable < tmpLength - 4)
            {
                lastReservedLength = tmpLength;
                break;
            }
        }
        
        // CASE 4: A complete package received once
        
        // Generate ByteArray of a complete package
        var resultBytes:ByteArray = new ByteArray();
        resultBytes.writeInt(tmpLength);
        _socket.readBytes(resultBytes, 4, tmpLength - 4);
        lastReservedLength = 0;
        
        // parse the ByteArray
        resultBytes.position = 0;
        var resProto:Object = CppLibUtil.parseMediaProto(resultBytes);
        
        // Dispatch the ByteArray
        if (resProto != null) {
            
            var uri:String;
            
            try {
                uri = resProto.uri;
            } catch (e:Event) {
                trace(e);
            }
                
            dispatchEvent(new InternalEvent(uri, resProto));
        }
    }
}

-

转载请注明来自柳大的CSDN博客:Blog.CSDN.net/Poechant

-

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值