package gamePub.clientSocket { import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.events.SecurityErrorEvent; import flash.net.Socket; import flash.text.TextField; import flash.text.TextFormat; import flash.utils.ByteArray; import gamePub.ui.GPopInfo; import gsocket.GlobalManagement; public class ClientSocket extends Socket { public function ClientSocket(host:String=null, port:int=0) { super(host, port); addEventListener(Event.CONNECT, connectHandler); addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler); addEventListener(Event.CLOSE,onServerClosed); addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler); addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); } private var _readyToSend:Boolean = false; public function get readyToSend():Boolean { return _readyToSend; } private var _readyToClose:Boolean = false; public function get readyToClose():Boolean { return _readyToClose; } private var _readyToConnect:Boolean = true; public function get readyToConnect():Boolean { return _readyToConnect; } //成功建立和服务端得连接后 private function connectHandler(event:Event):void { _readyToConnect = false; _readyToSend = _readyToClose= true; trace("connectHandler"); } public var readyToRecv:Boolean = false; //可以接受数据 //成功接收到从服务端传来的一次数据 private function socketDataHandler(event:ProgressEvent):void { //trace("ClientSocket socketDataHandler"); readyToRecv = true; var recvStream:ByteArray = new ByteArray(); readBytes(recvStream,0,bytesAvailable); GlobalManagement.instance.recvMessageFromServer(recvStream); } //关闭套接字 public function closeClientSocket():void { if(this && connected) { removeEventListener(Event.CONNECT, connectHandler); removeEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler); removeEventListener(Event.CLOSE,onServerClosed); removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler); removeEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); close(); } _readyToConnect = true; _readyToSend = _readyToClose = false; } //服务端关闭后 private function onServerClosed(event:Event):void { trace("onServerClosed"); closeClientSocket(); } private function ioErrorHandler(event:IOErrorEvent):void { trace("ioErrorHandler"); closeClientSocket(); } private function securityErrorHandler(event:SecurityErrorEvent):void { closeClientSocket(); trace("security错误"); } } }
package gamePub.clientSocket { import pub.net.NetCenter; import flash.utils.ByteArray; import flash.utils.Endian; public class NetManagement { private static var _instance:NetManagement; public static function get instance():NetManagement { if(!_instance) { _instance = new NetManagement(); } return _instance; } private var _partData:ByteArray = new ByteArray(); //过长或者过短的数据包 _partData private var _packageQueue:Array = []; //数据包队列 存放ByteArray类型的元素 //填充需要处理的消息队列_packageQueue 参数value是服务器发送过来的字节流 private function fillMsgQueue(value:ByteArray):void { _partData.position = _partData.length; _partData.writeBytes(value); //value追加到_partData末尾 //处理_partData,使得_partData中没有数据包或者只有一个过短的数据包 var otherPack:PackageHead = new PackageHead(); otherPack.byteArray = _partData; //无包头 if(!otherPack.legal) { ////trace("断包 无包头"); _partData = new ByteArray(); } while(otherPack.legal) { if(otherPack.bodyLen < otherPack.body.length) { var pack2:ByteArray = new ByteArray(); pack2.writeBytes(_partData,0,otherPack.bodyLen+6); _packageQueue.push(pack2); //trace("连包"); // var pck:PackageHead = new PackageHead(); // pck.byteArray = pack2; // //trace("fillMsgQueue len cmd",pck.toByteArray().length,pck.cmd.toString(16)); var pack3:ByteArray = new ByteArray(); pack3.writeBytes(_partData,pack2.length); _partData = pack3; otherPack.byteArray = _partData; } else if(otherPack.bodyLen == otherPack.body.length) { _packageQueue.push(otherPack.toByteArray()); // //trace("fillMsgQueue len cmd",otherPack.toByteArray().length,otherPack.cmd.toString(16)); _partData = new ByteArray(); //清空_partData break; } else { //trace("断包 有包头"); break; } } } //服务器发信息到客户端,有可能去改变可视元素的关联数据 public function recvMessageFromServer(value:ByteArray):void { fillMsgQueue(value); while(_packageQueue.length > 0) { var pack:ByteArray = _packageQueue.shift(); processServerMsg(pack); } } //处理服务器发过来的正确数据包,value是长度正确的一个数据包 private function processServerMsg(value:ByteArray):void { var pack:PackageHead = new PackageHead(); pack.byteArray = value; //trace("processServerMsg pack len,command",pack.toByteArray().length,pack.cmd); var cmd:uint; //命令字 cmd = pack.cmd; //trace("pack cmd",cmd.toString(16)); pack.body.endian = Endian.LITTLE_ENDIAN; pack.body.position = 0; //判断数据完整 NetCenter.onReceivedMessage(cmd,pack.body); //分发消息 } /* public function useItemUpLevel(page:int,grid:int,id:Array):void { var body:ByteArray = new ByteArray(); body.endian = Endian.LITTLE_ENDIAN; body.writeByte(page) body.writeByte(grid) body.writeInt(id[0]) body.writeInt(id[1]) var pack:PackageHead = new PackageHead(body); pack.cmd = CommandEnum.CLGM_USEITEM_UPLEVEL_SHOP pack.sendMsg() }*/ } }
package gamePub.clientSocket { import pub.net.NetCenter; import flash.utils.ByteArray; import flash.utils.Endian; public class PackageHead { private const HEAD_FLAG:uint = 0xFFAA; private var _headFlag:uint; //标志位 unsigned short 用于辨别数据包的真伪 public static const MAX_SIZE:uint = 119; public var cmd:uint = CommandEnum.CLGM_CHAT; //命令字 用于区分数据包的类型,邮件包还是聊天包? private var _body:ByteArray; //和消息包头关联的消息包体 private var _legal:Boolean = true; //数据是否合法,默认合法 private var _bodyLen:uint; public function PackageHead(msg:ByteArray=null) { _headFlag = HEAD_FLAG; _body = msg; } public function get body():ByteArray { return _body; } public function get legal():Boolean { return _legal; } public function get bodyLen():uint { return _bodyLen; } public function set byteArray(value:ByteArray):void { if(value) { value.position = 0; value.endian = Endian.LITTLE_ENDIAN; _headFlag = value.readUnsignedShort(); if(_headFlag != HEAD_FLAG) { _legal = false; return ; } cmd = value.readUnsignedShort(); _bodyLen = value.readUnsignedShort(); _body = new ByteArray(); _body.writeBytes(value,6,value.length-6); } } public function toByteArray():ByteArray //把packageHead转换为对应的ByteArray { var byteStream:ByteArray = new ByteArray(); byteStream.endian = Endian.LITTLE_ENDIAN; byteStream.writeShort(HEAD_FLAG); byteStream.writeShort(cmd); if(_body) { byteStream.writeShort(_body.length); byteStream.writeBytes(_body); } else { byteStream.writeShort(0); } return byteStream; } //发送消息包给服务器 发送成功返回true public function sendMsg():Boolean { if(NetCenter.m_clientSocket && NetCenter.m_clientSocket.connected) { NetCenter.m_clientSocket.writeBytes(toByteArray(),0,toByteArray().length); NetCenter.m_clientSocket.flush(); // trace("sendMsg:true"); return true; } // trace("sendMsg:false"); return false; } } }