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
-