Flash Socket底层接受数据的初级处理

flash开发 应用 ,,免不了网络通讯,特别是网络游戏 ,需要用到即使通讯。
as3 提供了两个支持即时通讯的类:XML Socket 和Socket,前者其实是只支持发送字符串,而后者就强大多了,支持发送字节,相对来说比较底层,而这也给我们更多的发挥空间。
其实,flash socket的网络底层接受数据 ,就以与C++服务器通讯为例子,C++服务器一般会发一段一段数据过来,每段数据都是由一定结构组成的,一般是消息头和消息头,然后再逐步分层解析。
在这里,我只说接受网络底层的处理,一般一段数据前面,还有有一个4个字节左右的数据,表示的是后面网络流里的数据有多少....
看下简单示意图
net1.jpg


我们网络底层需要做的处理,就是根据头4个字节判断出后面的数据大小,然后把那一整块取出来,抛给上层解析,然后又在不停地侦听,
收到指定大小之后,又做类似的操作,下面看详细的代码


/**
 * @(#)NetBottomHandle.as
 * @author soda.C  mail:sujun10@21cn.com
 * @version  1.0
 *
Copyright (C), 2008 soda.C
 *
This program is protected by copyright laws.
 *
Program Name:GameHall
 * @data 2008-3-20
 */
package org.sujun.net
{
        import flash.net.Socket;
        import flash.events.ProgressEvent;
        import flash.utils.ByteArray;
        /**
         * socket数据流里的底层处理,从这里接受到服务器的数据,满足条件后就会抛出需要的字节
         * 对数据流的数据,不做任何处理
         *
         * @author soda.C
         */
        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();
                        isReadHead = true;
                }
                /**
                 * 设置一个网络通讯实例
                 */ 
                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 = true;
                                }
                        }
                        //如果数据流里还满足读取数据条件,继续读取数据
                        if(socket.bytesAvailable >= headLen)
                        {
                                parseNetData();
                        }
                }
        }
}


代码我就不详细解说了,注释得很清楚,这段代码也是经过我写过几个版本锤炼过的。呵呵
在实际应用中,表现也是比较稳定的
当然,这是比较早期的了,以后再正正应用中,可能还需要做更多的处理,例如每个网络字节的缓冲,缓存等,以免过多字节造成socket出错等等
希望有兴趣的人继续留贴讨论,呵呵
NetBottomHandle.rar (1.51 KB)


修改了下代码的错误之后,如果要看详细的,整个流程,包括服务端的代码的话,请看这边文章吧
http://www.sujun.org/article.asp?id=51

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值