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);
}
}
}

posted on 2011-09-28 15:53  AS3.0  阅读(1952)  评论(0)    收藏  举报

导航