Flash Socket 底层接受数据的初级处理(as3.0)
2010-09-29 16:15
337 查看
用flash去开发应用,,免不了网络通讯,特别是网络游戏,需要用到即使通讯。
as3提供了两个支持即时通讯的类:XMLSocket和Socket,前者其实是只支持发送字符串,而后者就强大多了,支持发送字节,相对来说比较底
层,而这也给我们更多的发挥空间。
其实,flash socket的网络底层接受数据,就以与C++服务器通讯为例子,C++服务器一般会发一段一段数据过来,每段数据都是由一定结构组成
的,一般是消息头和消息头,然后再逐步分层解析。
在这里,我只说接受网络底层的处理,一般一段数据前面,还有有一个4个字节左右的数据,表示的是后面网络流里的数据有多少.... 看下简单示意图
我们网络底层需要做的处理,就是根据头4个字节判断出后面的数据大小,然后把那一整块取出来,抛给上层解析,然后又在不停地侦听,收到指定大小之后,又做类似的操作,下面看详细的代码
/**
* @(#)NetBottomHandle.as
* @author soda.C mail:sujun10@21cn.com
* @version 1.0
* <br>Copyright (C), 2007 soda.C
* <br>This program is protected by copyright laws.
* <br>Program Name:GameHall
* @data 2008-3-20
*/
package
org.sujun.net
{
import
flash.net.Socket;
import
flash.events.ProgressEvent;
import
flash.utils.ByteArray;
/**
* socket数据流里的底层处理,从这里接受到服务器的数据,满足条件后就会抛出需要的字节
* 对数据流的数据,不做任何处理
*/
public
class
NetBottomHandle
{
private
var
socket :Socket;
private
var
listener :Function; //接受网络解析出来的数据
private
var
msgLen :int
; //消息长度
private
var
msgLenMax :int
; //收到的消息最大长度
private
var
headLen :int
; //消息头长度
private
var
isReadHead :Boolean; //是否已经读了消息头
private
var
bytes :ByteArray; //所读数据的缓冲数据,读出的数据放在这里
public
function
NetBottomHandle()
{
msgLenMax = 5000; //5000字节
headLen = 4; //4个字节
bytes = new
ByteArray();
}
/**
* 设置一个网络通讯实例
*/
public
function
setSocket(socket:Socket):void
{
this
.socket = socket;
//监听......
socket.addEventListener(ProgressEvent.SOCKET_DATA, onServerData,false
,0,true
);
}
/**
* 接受在网络层里收到的原始数据,传递过来的数据为描述长度,以及ByteArray对象functon(len,bytes)
* @param listener:接受数据函数
*/
public
function
receiverNetData(listener:Function):void
{
this
.listener = listener;
}
/**
* 服务器发送过来的数据都在这里接收,最底层的
*/
private
function
onServerData(event:ProgressEvent):void
{
//一有收到数据的事件,就通过这个函数进行检验
parseNetData();
}
/**
* 解析网络数据流
*/
private
function
parseNetData():void
{
//如果需要读信息头
if
(isReadHead)
{
if
(socket.bytesAvailable >= headLen)
{
//读出指示后面的数据有多大
msgLen = socket.readUnsignedInt();
isReadHead = false
;
}
}
//如果已经读了信息头,则看能不能收到满足条件的字节数
if
(!isReadHead && msgLen <= msgLenMax)
{
//如果为0,表示收到异常消息
if
(msgLen == 0)
{
//一般消息长度为0的话,表示与服务器出了错,或者即将被断开等,通知客户端,进行特别处理
listener(msgLen,null
);
return
;
}
//数据流里的数据满足条件,开始读数据
if
(socket.bytesAvailable >= msgLen)
{
//指针回归
bytes.position = 0;
//取出指定长度的网络字节
socket.readBytes(bytes, 0, msgLen);
listener(msgLen,bytes);
}
}
isReadHead = false
;
//如果数据流里还满足读取数据条件,继续读取数据
if
(socket.bytesAvailable >= headLen)
{
parseNetData();
}
}
}
}
代码我就不详细解说了,注释得很清楚,这段代码也是经过我写过几个版本锤炼过的。呵呵 在实际应用中,表现也是比较稳定的
当然,这是比较早期的了,以后再正正应用中,可能还需要做更多的处理,例如每个网络字节的缓冲,缓存等,以免过多字节造成socket出错等等
希望有兴趣的人继续留贴讨论,呵呵
点击下载此文件
as3提供了两个支持即时通讯的类:XMLSocket和Socket,前者其实是只支持发送字符串,而后者就强大多了,支持发送字节,相对来说比较底
层,而这也给我们更多的发挥空间。
其实,flash socket的网络底层接受数据,就以与C++服务器通讯为例子,C++服务器一般会发一段一段数据过来,每段数据都是由一定结构组成
的,一般是消息头和消息头,然后再逐步分层解析。
在这里,我只说接受网络底层的处理,一般一段数据前面,还有有一个4个字节左右的数据,表示的是后面网络流里的数据有多少.... 看下简单示意图
我们网络底层需要做的处理,就是根据头4个字节判断出后面的数据大小,然后把那一整块取出来,抛给上层解析,然后又在不停地侦听,收到指定大小之后,又做类似的操作,下面看详细的代码
/**
* @(#)NetBottomHandle.as
* @author soda.C mail:sujun10@21cn.com
* @version 1.0
* <br>Copyright (C), 2007 soda.C
* <br>This program is protected by copyright laws.
* <br>Program Name:GameHall
* @data 2008-3-20
*/
package
org.sujun.net
{
import
flash.net.Socket;
import
flash.events.ProgressEvent;
import
flash.utils.ByteArray;
/**
* socket数据流里的底层处理,从这里接受到服务器的数据,满足条件后就会抛出需要的字节
* 对数据流的数据,不做任何处理
*/
public
class
NetBottomHandle
{
private
var
socket :Socket;
private
var
listener :Function; //接受网络解析出来的数据
private
var
msgLen :int
; //消息长度
private
var
msgLenMax :int
; //收到的消息最大长度
private
var
headLen :int
; //消息头长度
private
var
isReadHead :Boolean; //是否已经读了消息头
private
var
bytes :ByteArray; //所读数据的缓冲数据,读出的数据放在这里
public
function
NetBottomHandle()
{
msgLenMax = 5000; //5000字节
headLen = 4; //4个字节
bytes = new
ByteArray();
}
/**
* 设置一个网络通讯实例
*/
public
function
setSocket(socket:Socket):void
{
this
.socket = socket;
//监听......
socket.addEventListener(ProgressEvent.SOCKET_DATA, onServerData,false
,0,true
);
}
/**
* 接受在网络层里收到的原始数据,传递过来的数据为描述长度,以及ByteArray对象functon(len,bytes)
* @param listener:接受数据函数
*/
public
function
receiverNetData(listener:Function):void
{
this
.listener = listener;
}
/**
* 服务器发送过来的数据都在这里接收,最底层的
*/
private
function
onServerData(event:ProgressEvent):void
{
//一有收到数据的事件,就通过这个函数进行检验
parseNetData();
}
/**
* 解析网络数据流
*/
private
function
parseNetData():void
{
//如果需要读信息头
if
(isReadHead)
{
if
(socket.bytesAvailable >= headLen)
{
//读出指示后面的数据有多大
msgLen = socket.readUnsignedInt();
isReadHead = false
;
}
}
//如果已经读了信息头,则看能不能收到满足条件的字节数
if
(!isReadHead && msgLen <= msgLenMax)
{
//如果为0,表示收到异常消息
if
(msgLen == 0)
{
//一般消息长度为0的话,表示与服务器出了错,或者即将被断开等,通知客户端,进行特别处理
listener(msgLen,null
);
return
;
}
//数据流里的数据满足条件,开始读数据
if
(socket.bytesAvailable >= msgLen)
{
//指针回归
bytes.position = 0;
//取出指定长度的网络字节
socket.readBytes(bytes, 0, msgLen);
listener(msgLen,bytes);
}
}
isReadHead = false
;
//如果数据流里还满足读取数据条件,继续读取数据
if
(socket.bytesAvailable >= headLen)
{
parseNetData();
}
}
}
}
/** * @(#)NetBottomHandle.as * @author soda.C mail:sujun10@21cn.com * @version 1.0 * <br>Copyright (C), 2007 soda.C * <br>This program is protected by copyright laws. * <br>Program Name:GameHall * @data 2008-3-20 */ package org.sujun.net { import flash.net.Socket; import flash.events.ProgressEvent; import flash.utils.ByteArray; /** * socket数据流里的底层处理,从这里接受到服务器的数据,满足条件后就会抛出需要的字节 * 对数据流的数据,不做任何处理 */ public class NetBottomHandle { private var socket :Socket; private var listener :Function; //接受网络解析出来的数据 private var msgLen :int; //消息长度 private var msgLenMax :int; //收到的消息最大长度 private var headLen :int; //消息头长度 private var isReadHead :Boolean; //是否已经读了消息头 private var bytes :ByteArray; //所读数据的缓冲数据,读出的数据放在这里 public function NetBottomHandle() { msgLenMax = 5000; //5000字节 headLen = 4; //4个字节 bytes = new ByteArray(); } /** * 设置一个网络通讯实例 */ public function setSocket(socket:Socket):void { this.socket = socket; //监听...... socket.addEventListener(ProgressEvent.SOCKET_DATA, onServerData,false,0,true); } /** * 接受在网络层里收到的原始数据,传递过来的数据为描述长度,以及ByteArray对象functon(len,bytes) * @param listener:接受数据函数 */ public function receiverNetData(listener:Function):void { this.listener = listener; } /** * 服务器发送过来的数据都在这里接收,最底层的 */ private function onServerData(event:ProgressEvent):void { //一有收到数据的事件,就通过这个函数进行检验 parseNetData(); } /** * 解析网络数据流 */ private function parseNetData():void { //如果需要读信息头 if(isReadHead) { if(socket.bytesAvailable >= headLen) { //读出指示后面的数据有多大 msgLen = socket.readUnsignedInt(); isReadHead = false; } } //如果已经读了信息头,则看能不能收到满足条件的字节数 if(!isReadHead && msgLen <= msgLenMax) { //如果为0,表示收到异常消息 if(msgLen == 0) { //一般消息长度为0的话,表示与服务器出了错,或者即将被断开等,通知客户端,进行特别处理 listener(msgLen,null); return ; } //数据流里的数据满足条件,开始读数据 if(socket.bytesAvailable >= msgLen) { //指针回归 bytes.position = 0; //取出指定长度的网络字节 socket.readBytes(bytes, 0, msgLen); listener(msgLen,bytes); } } isReadHead = false; //如果数据流里还满足读取数据条件,继续读取数据 if(socket.bytesAvailable >= headLen) { parseNetData(); } } } }
代码我就不详细解说了,注释得很清楚,这段代码也是经过我写过几个版本锤炼过的。呵呵 在实际应用中,表现也是比较稳定的
当然,这是比较早期的了,以后再正正应用中,可能还需要做更多的处理,例如每个网络字节的缓冲,缓存等,以免过多字节造成socket出错等等
希望有兴趣的人继续留贴讨论,呵呵
点击下载此文件
相关文章推荐
- Flash Socket 底层接受数据的初级处理(as3.0)
- Flash Socket 底层接受数据的初级处理(as3.0)
- [AS3]Flash Socket底层接受数据的初级处理
- Flash Socket底层接受数据的初级处理
- [AS3]Flash Socket底层接受数据的初级处理(转)
- Flash Socket底层接收数据的初级处理
- Flash Socket 底层接受数据的初级处理(as3.0)
- 每天学一点flash(14) as3.0 处理xml (官方)
- socket接受数据的三种方式
- 异步Socket接收数据后缓存处理问题
- Socket之iOS项目中的socket应用/IPV6 转换/域名转IP/解析socket接受的数据/心跳包
- UDP的socket绑定到IP地址后无法接受广播数据
- socket--接受大数据
- AJAX异步请求,底层使用hibernate查询后的数据json封装之前的处理
- 即时通讯下数据粘包、断包处理实例(基于CocoaAsyncSocket)
- 计算机底层数据的处理方式
- cjson libcurl 发送请求给python 接受数据和处理数据 参考了一下别人的方法
- ijkplayer播放器的read_thread数据接受线程在处理音频的时候如果首个数据包没有发现audio stream 以后就不会有音频数据
- Intel DAAL AI加速——支持从数据预处理到模型预测,数据源必须使用DAAL的底层封装库
- Flash处理外部XML文档数据详细教程