原文:http://www.sujun.org/article.asp?id=51
actionscript3.0 Socket通信实例文章收藏:http://as3.aa-a.net/index.php/as3-socket-communication-examples.html
http://blessht.iteye.com/blog/1136888
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 连接服务器需要安全策略验证时,会向服务端发送特定的字符串信息:"
2. 服务端在验证到这个字符串之后,马上给Flash返回策略文件。客户端收到策略文件之后会断开重新连接该服务器(假设正确的策略文件)
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 {} |