您的位置:首页 > 其它

Flash Socket 的基本通讯协议流程例子

2012-05-09 09:30 267 查看
原文:http://www.sujun.org/article.asp?id=51

actionscript3.0 Socket通信实例文章收藏:http://as3.aa-a.net/index.php/as3-socket-communication-examples.html

/content/2670615.html: ( flash builder 开发客户端,Java 开发Server )

Flash Socket 的两种 API:

1. XMLSocket

AS2.0时采用的socket通讯类,在AS3.0时依然保留。该类只能通过发送字符串,一般发送XML格式的字符号串到服务端

2. Socket

AS3.0才拥有的对象,可以传输精确到字节(Byte),可以充分发挥网络通讯的功能了。

Flash Socket 好助手 ByteArray:

1. ByteArray 类提供用于优化读取、写入以及处理二进制数据的方法和属性

2. 在这里主要是利用ByteArray做数据缓存,把socket中的数据都取出来在ByteArray中存放,这样只操作ByteArray,安全。

Flash 的安全策略机制:

1. 当 Flash 连接服务器需要安全策略验证时,会向服务端发送特定的字符串信息:"<policy-file-request/>"

2. 服务端在验证到这个字符串之后,马上给Flash返回策略文件。客户端收到策略文件之后会断开重新连接该服务器(假设正确的策略文件)

<cross-domain-policy>

<allow-access-from domain="*" to-ports="* "/>

</cross-domain-policy>

Socket 字节传输的协议结构:

1. 根据socket发送字节特性,可以自定义通讯协议,从而提高了协议的灵活性。

2. 最基础的协议结构:传输内容长度+ 传输具体内容(len + body)

3. 说明:这是最基本的传输格式,每次发一段数据给服务器的时候,都先声明一个长度(int,4byte),表示后面多少字节的内容是这次消息的具体内容(多少byte)

客户端相关代码:

socket = new Socket();
//监听socket事件
socket.addEventListener(Event.CONNECT,onConnected);
socket.addEventListener(Event.CLOSE,onClosed);
socket.addEventListener(IOErrorEvent.IO_ERROR,ioError);
socket.addEventListener(ProgressEvent.SOCKET_DATA,onData);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityError);

private function onConnected(evt:Event):void
{
userName = "soda" + Math.floor(Math.random() * 100000);
//连接成功,进行发送数据
var byteArray:ByteArray = new ByteArray();
//登陆消息
byteArray.writeShort(LOGIN);
byteArray.writeUTF(userName);
socket.writeShort(byteArray.length);
socket.writeBytes(byteArray);
socket.flush();
}

private function ioError(event:IOErrorEvent):void
{
trace("连接socket服务器错误");

}
private function onClosed(evt:Event):void
{
trace("socket closed");
}
private function securityError(event:SecurityErrorEvent):void
{
trace("SecurityErrorEvent");
}

private function onData(evt:ProgressEvent):void
{
//一有收到数据的事件,就通过这个函数进行检验
parseNetData();
}

//解析对应的网路数据
private function parseProtocol():void
{
var moveX:int = 0;
var moveY:int = 0;
//解析出cmd
var cmd:int = bytes.readShort();
switch(cmd)
{
case OTHER_USERS:
//处理玩家进入
var user:User = new User();
var otherName:String = bytes.readUTF();
var isHero:Boolean = false;
moveX = bytes.readShort();
moveY = bytes.readShort();
if(otherName == userName)
{
//初始化一个角色
hero = user;
isHero = true;
}
addChild(user);
user.setUserName(otherName,isHero);
user.x = moveX;
user.y = moveY;
userMap[otherName] = user;
trace("有用户进入....." + otherName);
break;
case MOVE:
//解析移动协议
var moveName:String = bytes.readUTF();
moveX = bytes.readShort();
moveY = bytes.readShort();
//取出对应的用户
var moveUser:User = userMap[moveName];
if(moveUser != null)
{
moveUser.x = moveX;
moveUser.y = moveY;
}
break;
case EXIT:
var exitName:String = bytes.readUTF();
//取出对应的用户
var exitUser:User = userMap[exitName];
userMap[exitName] = null;
if(exitUser != null)
{
removeChild(exitUser);
}
break;
}
}


AS3 发送指定长度指定编码的固定字符串(解决乱码问题):

var msg:String = "my name is soda";
var byte = new ByteArray();
byte.writeMultiByte(msg, "gb2312");  //指定字符编码集
byte.length = 32;
socket.writeBytes(byte);


Socket & AMF3:

// Socket比起原来的XMLSocket来说,增加了可传递二进制数据,而AMF3则可以封装很多类型的数据
// 发送代码;
var bytes:ByteArray = new ByteArray();
bytes.writeObject( { event:"send", message:input.text } );
input.text = "";
bytes.compress();
socket.writeBytes(bytes);
socket.flush();

// 接收代码;
var bytes:ByteArray = new ByteArray();
socket.readBytes(bytes);
bytes.uncompress();
var object:Object = bytes.readObject();


registerClassAlias() 函数的使用(序列化、反序列化相关):

当以 Action Message Format (AMF) 对一个对象进行编码时,保留该对象的类(类型)。 将对象编码为 AMF 时,该函数将保存该对象的类的别名,以便在解码对象时可以恢复该类。 如果编码上下文没有为对象的类注册别名,该对象将被编码为一个匿名对象。 同样,如果解码上下文注册了不同的别名,将为解码后的数据创建一个匿名对象。

此示例使用 registerClassAlias() 函数为 ExampleClass
注册一个别名 ( com.example.eg )。 由于为类注册了别名,因此可以将对象作为 ExampleClass 的实例反序列化,且代码将输出 true。 如果删除 registerClassAlias() 调用,则代码将输出 false。

package {
import flash.display.Sprite;
import flash.net.registerClassAlias;
import flash.utils.ByteArray;

public class RegisterClassAliasExample extends Sprite {
public function RegisterClassAliasExample() {
registerClassAlias("com.example.eg", ExampleClass);
var eg1:ExampleClass = new ExampleClass();
var ba:ByteArray = new ByteArray();
ba.writeObject(eg1);
ba.position = 0;
var eg2:* = ba.readObject();
trace(eg2 is ExampleClass); // true
}
}
}

class ExampleClass {}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: