FLASH端SOCKET连接C++服务端代码
最近在开发一个休闲类的游戏,用到了socket通讯方面的信息,今天整理了下,很多都是从网上找到的,大致就是包括:连接socket,发包,解包的处理。
package xygame.net
{
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
import flash.net.Socket;
import flash.system.Security;
import flash.utils.ByteArray;
import flash.utils.Endian;
import xygame.events.ConnectionEvent;
import xygame.interfaces.IConnection;
import xygame.interfaces.IMsg;
public class Connection extends EventDispatcher
{
/** 服务器地址 */
private var _server:String;
/** 服务器端口 */
private var _port:int;
/** 通信socket */
private var _socket:Socket;
/** 字节流缓冲池 */
private var _buffer:ByteArrayBuffer;
private var _conn:Connection;
public function Connection()
{
super();
_buffer = new ByteArrayBuffer();
_conn = this;
}
private var _isConnecting:Boolean = false;
/**
* 连接服务器
* @param vServer:String 服务器地址
* @param vPort:int 服务器端口
* @return
*/
public function connect(vServer:String,vPort:int):void
{
if(_socket == null)
_socket = new Socket();
_server = vServer;
_port = vPort;
//添加侦听器
addListener();
if(_socket.connected)
_socket.close();
output("连接服务器 ... server- " + vServer + " port-" + vPort,this);
//安全策略
var policyFile:String="xmlsocket://" + _server + ":" + _port;
Security.loadPolicyFile(policyFile);
//连接服务器
_socket.connect(_server,_port);
_isConnecting = true;
}
/**
* 关闭服务器连接
*/
public function close():void
{
if(isConnected)
_socket.close();
}
/**
* 向服务器端发送数据
* @param vMsg:IMsg 要发送的数据
*/
public function sendMsg(vMsg:IMsg):void
{
if(!isConnected)
{
output("sendMsg : 连接服务器断开",_server,_port,this);
dispathFaildEvent(ConnectionEvent.CLOSE_ERROR,false);
return;
}
var ba:ByteArray = MsgUtil.encodeByteArray(vMsg.msgData);
ba.position = 0;
_socket.writeBytes(ba,0,ba.length);
_socket.flush();
}
/**
* 连接是否还在-
*/
public function get isConnected():Boolean
{
return (_socket && _socket.connected);
}
private function addListener():void
{
_socket.removeEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);
_socket.removeEventListener(SecurityErrorEvent.SECURITY_ERROR,securityErrorHandler);
_socket.removeEventListener(Event.CLOSE,closeHandler);
_socket.removeEventListener(Event.CONNECT,connectHandler);
_socket.removeEventListener(ProgressEvent.SOCKET_DATA,socketDataHandler);
_socket.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);
_socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityErrorHandler);
_socket.addEventListener(Event.CLOSE,closeHandler);
_socket.addEventListener(Event.CONNECT,connectHandler);
_socket.addEventListener(ProgressEvent.SOCKET_DATA,socketDataHandler);
}
private function ioErrorHandler(vEvt:IOErrorEvent):void
{
_isConnecting = false;
output(" ioError:连接服务器失败" + sinfo,this);
dispathFaildEvent(ConnectionEvent.IO_ERROR)
}
private function securityErrorHandler(vEvt:SecurityErrorEvent):void
{
_isConnecting = false;
output(" SecurityError:连接服务器失败" + " (" + vEvt.text + ") " + sinfo,this);
//因为每次close都会同时抛出这个事件
dispathFaildEvent(ConnectionEvent.SECURITY_ERROR,false);
}
private function closeHandler(vEvt:Event):void
{
_isConnecting = false;
output(" close:连接关闭" + sinfo,this);
dispathFaildEvent(ConnectionEvent.CLOSE_ERROR);
}
public function get sinfo():String
{
return " ( " + _server + "-" + _port + " ) ";
}
/** 失败重连次数 */
private var _failJsq:int = 0;
/** 是否第一次连接(除非连接成功一次,否则都算第一次) */
private var _firstConn:Boolean = true;
/** 是否允许失败重连 */
public var canReconn:Boolean = false;
/** 发布失败事件
* @param vType:String 失败的类型 */
public function dispathFaildEvent(vType:String,isRetry:Boolean = true):void
{
_failJsq += 1;
if(canReconn && _firstConn && _failJsq >= 3)
{
output("连接失败 " + _failJsq + " 次,重试ing...",this);
if(isRetry && !_isConnecting)
connect(_server,_port);
}
else
{
output("连接失败了。。。" + vType,this);
var event:ConnectionEvent = new ConnectionEvent(ConnectionEvent.CONN_FAILD);
event.faildType = vType;
dispatchEvent(event);
}
}
private function connectHandler(vEvt:Event):void
{
_isConnecting = false;
_firstConn = false;
output(" 连接服务器成功!!!!!!!" + sinfo,this);
var event:ConnectionEvent = new ConnectionEvent(ConnectionEvent.CONN_SUCCESS);
dispatchEvent(event);
}
/** 接收到字节流数据,先放到缓冲池,再调用分包方法分包,然后再讲每个包都分发出去 */
private function socketDataHandler(vEvt:ProgressEvent):void
{
var ba:ByteArray = MsgUtil.createByteArray();
_socket.readBytes(ba,0,vEvt.bytesLoaded);
//讲读取到的数据加入缓冲池
_buffer.cacheBytes(ba);
//触发缓冲池的拆分包方法,讲字节流拆分成一个个的包
var packages:Array = _buffer.splitBufferToPackage();
for(var i:int = 0 ; i < packages.length ; i++)
receiveMsg(packages[i]);
}
/** 将接收到的字节流数据转发出去 */
private function receiveMsg(vBa:ByteArray):void
{
var ba:ByteArray = MsgUtil.decodeByteArray(vBa);
if(ba == null)
return ;
var msg:MessageData = new MessageData(ba);
var event:ConnectionEvent = new ConnectionEvent(ConnectionEvent.RECEIVE_MESSAGE);
event.msg = msg;
dispatchEvent(event);
}
}
}
浙公网安备 33010602011771号