ActionScript简单实现Socket Tcp应用协议分析器

时间:2021-11-07 01:35:20
转自。。smark http://www.cnblogs.com/smark/archive/2012/05/15/2501507.html

ActionScript简单实现Socket Tcp应用协议分析器

    其实Flash上做通讯很多情况都选择AMF,毕竟他是AS内部基于对象进制序列协议,容量小效率高。但有时为了去调用一些已经有的Tcp服务,而这些服务并不是提供AMF支持;这时你就不得不实现一个协议的分析。其实AS提ByteArray提供了很多write和read方法,这样使我们应用起来非常方便。以下是用AS简单封装基于消息头描述大小的协议分析器。

    为了更好地管理消息,通过一接口来制写消息写入和读取规范。

package Beetle.AS
{
import flash.utils.ByteArray;
public interface IMessage
{
function Load(data:Reader):void;
function Save(data:Writer):void;
}
}
  接口比较简单分别是保让到流中和从流中获取,其中Reader和Writer都派生于ByteArray对象;为什么没有直接用ByteArray呢?其原因就可以自己实现更高级的信息获取方法. package Beetle.AS
{
import flash.net.getClassByAlias;
import flash.utils.ByteArray;
import flash.utils.getDefinitionByName;
import mx.controls.Image;
public class Reader extends ByteArray
{
public function Reader()
{
super();
}
public function ReadMessages(className:String):Vector.<IMessage>
{
var results:Vector.<IMessage> = new Vector.<IMessage>();
for(var i:int=0;i<readInt();i++)
{
var msg:IMessage = IMessage(getDefinitionByName(className));
results.push(msg);
}
return results;
}
}
}
package Beetle.AS
{
import flash.utils.ByteArray;
public class Writer extends ByteArray
{
public function Writer()
{
super();
}
public function WriteMessages(items:Vector.<IMessage>):void
{
writeInt(items.length);
for each(var item:IMessage in items)
{
item.Save(this);
}
}
}
}
  基础规则都构建好了,下面就开始做协议分析部分。 package Beetle.AS
{
import flash.net.Socket;
import flash.utils.ByteArray;
import flash.utils.Endian;
import mx.graphics.shaderClasses.ExclusionShader;
public class HeadSizeOfPackage
{
public function HeadSizeOfPackage()
{
mWriter.endian = Endian.LITTLE_ENDIAN;
mReader.endian = Endian.LITTLE_ENDIAN;
}
private var mMessageReceive:Function;
//消息接收回调函数
public function get MessageReceive():Function
{
return mMessageReceive;
}
public function set MessageReceive(value:Function):void
{
mMessageReceive = value;
}
//写入消息类型标识
protected function WriteMessageTag(message:IMessage,data:Writer):void
{
throw new Error("WriteMessageTag not implement!");
}
//获取消息对象
protected function GetMessageByTag(data:Reader):IMessage
{
throw new Error("GetMessageByTag not implement!");
}
private var mReader:Reader = new Reader();
private var mSize:int=0;
//导入当前Socket接收的数据
public function Import(socket:Socket):void
{
socket.endian = Endian.LITTLE_ENDIAN;
while(socket.bytesAvailable>0)
{
if(mSize==0)
{
mSize= socket.readInt()-4;
mReader.clear();
}
if(socket.bytesAvailable>= mSize)
{
socket.readBytes(mReader,mReader.length,mSize);
var msg:IMessage = GetMessageByTag(mReader);
msg.Load(mReader);
if(MessageReceive!=null)
MessageReceive(msg);
mSize=0;
}
else{
mSize= mSize-socket.bytesAvailable;
socket.readBytes(mReader,mReader.length,socket.bytesAvailable);
}
}
}
private var mWriter:Writer = new Writer();
//发磅封装的协议数据
public function Send(message:IMessage,socket:Socket):void
{
socket.endian = Endian.LITTLE_ENDIAN;
mWriter.clear();
WriteMessageTag(message,mWriter);
message.Save(mWriter);
socket.writeInt(mWriter.length+4);
socket.writeBytes(mWriter,0,mWriter.length);
socket.flush();
}
}
}
  协议分析器的实现比较简单,基础功能有消息封装,对流进行分析还源对象并把消息回调到指定的函数中.MessageReceive是一个指向函数的属性,用于描述消息接收工作其原理类似于C#的委托。分析器中还有两个方法需要派生类重写WriteMessageTag和GetMessageByTag,其主要作用是写入消息类型标记和根据读取的标记信息创建相关联的对象。 Send方法是一个协议包装过程,主要把对象写入流的信息加工后用指定的Socket对象发送出去。 public function Send(message:IMessage,socket:Socket):void
{
socket.endian = Endian.LITTLE_ENDIAN;
mWriter.clear();
WriteMessageTag(message,mWriter);
message.Save(mWriter);
socket.writeInt(mWriter.length+4);
socket.writeBytes(mWriter,0,mWriter.length);
socket.flush();
}
  工作原理是通过消息接口的Save方法把对象信息写入到流中,第一步是先写入消息类型标记具体写入方法由派生类来确用string或int都可以,然后再写入消息内容;最后计算所有数据长度的头写入到socket再写入信息流即可。 Import方法是一个数据导入工作,主要负责从Socket中读取数据进行加载分析。 public function Import(socket:Socket):void
{
socket.endian = Endian.LITTLE_ENDIAN;
while(socket.bytesAvailable>0)
{
if(mSize==0)
{
mSize= socket.readInt()-4;
mReader.clear();
}
if(socket.bytesAvailable>= mSize)
{
socket.readBytes(mReader,mReader.length,mSize);
var msg:IMessage = GetMessageByTag(mReader);
msg.Load(mReader);
if(MessageReceive!=null)
MessageReceive(msg);
mSize=0;
}
else{
mSize= mSize-socket.bytesAvailable;
socket.readBytes(mReader,mReader.length,socket.bytesAvailable);
}
}
}
  原理很简单如果当前需要加载的数据为零,则表示为一个表新的消息;读取该消息需要加载的数据的长度,然后从Socket读取数据写入到流中,值到读取的长度和当前消息长度一致的情况就加载消息,并通过回调函数把消息回调到具体的工作方法中. 到这里一个以头4字节描述的消息分析器就完成,直接下来就是使用这个分析器。派生出一个新的分析器,并根据实际的需要实现对消息标记的处理. public class HeadSizePackage extends HeadSizeOfPackage
{
public function HeadSizePackage()
{
super();
}
override protected function GetMessageByTag(data:Reader):IMessage
{
var name:String = data.readUTF();
switch(name)
{
case "Register":
return new Register();
case "User":
return new User();
case "GetUser":
return new GetUser();
default :
return null;
}
}
override protected function WriteMessageTag(message:IMessage, data:Writer):void
{
if(message is Register)
{
data.writeUTF("Register");
}
else if(message is User)
{
data.writeUTF("User");
}
else if(message is GetUser){
data.writeUTF("GetUser");
}
else
{
data.writeUTF("NULL");
} }
}
  对于消息对象的实现也很简单,只要实现IMessage接口即可 public class Register implements IMessage
{
public function Register()
{
}
public var UserName:String;
public var EMail:String
public function Load(data:Reader):void
{
UserName= data.readUTF();
EMail = data.readUTF();
}
public function Save(data:Writer):void
{
data.writeUTF(UserName);
data.writeUTF(EMail);
}
}
  发送这个消息也比较简单 var reg:Register= new Register();
reg.UserName = txtUserName.text;
reg.EMail = txtEmail.text;
mPackage.Send(reg,mSocket);
  在使用AS的Socket时发现其实挺方便,很多基础的方法socket提供,即使是ByteArray也提供这些基础而又贴心的方法。

ActionScript简单实现Socket Tcp应用协议分析器的更多相关文章

  1. Http&comma;Socket&comma;TCP&sol;IP 协议简述

    Http,Socket,TCP/IP 协议简述:https://blog.csdn.net/gordohu/article/details/54097841 TCP/IP协议,HTTP协议与webSo ...

  2. 简单聊聊HTTP&sol;TCP&sol;IP协议

    经过几天的面试,有很多公司的面试官都会问到是否了解HTTP/TCP/IP协议? 一遇到这个问题,就一脸懵逼,虽然是计算机基层的东西,看来是必须得了解的,回到家之后,就查找了一些资料,整理了一篇博客,简 ...

  3. 简单使用SOCKET&comma;TCP&comma;UDP模式之间的通信

    TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议,由IETF的RFC 793定义.在简化的计算机网络OSI模型中, ...

  4. 使用Beetle简单构建高性能Socket tcp应用

    beetle是基于c#编写的高性能Socket tcp组件,它基于SocketAsyncEventArgs的实现并提供了发送队列和接收队列的支持,可以根据情况灵活地设置1-N个发送队列和接收队列.除了 ...

  5. socket、tcp&sol;ip协议、udp协议

    socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. socket起源于Un ...

  6. TCP&sol;IP 协议介绍

    转自http://blog.jobbole.com/104886/ 一.TCP/IP 协议介绍 在介绍 HTTP 协议之前,先简单说一下TCP/IP协议的相关内容.TCP/IP协议是分层的,从底层至应 ...

  7. 门面模式的典型应用 Socket 和 Http(post,get)、TCP&sol;IP 协议的关系总结

    门面模式的一个典型应用:Socket 套接字(Socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元.它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息: 连接使用的 ...

  8. TCP&sol;IP协议学习&lpar;四&rpar; 基于C&num; Socket的Web服务器---静态资源处理

    目录 1. C# Socket通讯 2. HTTP 解析引擎 3. 资源读取和返回 4. 服务器测试和代码下载 Web服务器是Web资源的宿主,它需要处理用户端浏览器的请求,并指定对应的Web资源返回 ...

  9. TCP&sol;IP协议学习&lpar;五&rpar; 基于C&num; Socket的C&sol;S模型

    TCP/IP协议作为现代网络通讯的基石,内容包罗万象,直接去理解理论是比较困难的:然而通过实践先理解网络通讯的理解,在反过来理解学习TCP/IP协议栈就相对简单很多.C#通过提供的Socket API ...

随机推荐

  1. vs2015提示中文

    解决方案:   1.找到这个目录 C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework 进入 \v ...

  2. Word Ladder

    Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest t ...

  3. WEP无线加密破解

    工具:Aircrack套件(airmon-ng.airodump-ng.aireplay-ng) 带有套件的操作系统:KaLi Linux.BackTrack.Beini(奶瓶)...等 1.开启无线 ...

  4. hdu2089 不要62--经典数位DP

    一道十分经典的数位DP的题目. dp[i][j]表示最高位是数字i,连同最高位在内共有j位.注意边界的初始化. 接下来就是区间划分,特殊情况处理.....对了,如果不知道自己的方法是否正确,可以写一个 ...

  5. UNIX环境高级编程——信号基本概述和signal函数

    一.为了理解信号,先从我们最熟悉的场景说起:1. 用户输入命令,在Shell下启动一个前台进程.2. 用户按下Ctrl-C,这个键盘输入产生一个硬件中断.3. 如果CPU当前正在执行这个进程的代码,则 ...

  6. vim详解

    vim介绍: 1.vim是vi的升级版本 2.vim是带有颜色显示的 3.vim三个模式:一般模式.编辑模式.命令模式 最小化模式下默认是没有安装vim的: [root@linux-xl ~]# yu ...

  7. 使用intellJ导入非maven&comma;gradle等非构建工程的依赖&comma;发布工程时候的打包详解

    一.导入 1.java项目在没有导入该jar包之前,如图: 2.点击 File ->  Project Structure(快捷键 Ctrl + Alt + Shift + s),点击Proje ...

  8. c&num; Newtonsoft&period;Json封装

    public static T Deserialize<T>(string content) where T : class, new() { return JsonConvert.Des ...

  9. 是否需要主动调用Bitmap的recycle方法

    一个Bitmap使用完后,是只需要等它成为垃圾后让GC去回收,还是应该主动调用recycle方法呢?或者说,主动调用recycle方法是否有好处,是否能马上回收内存呢? 带着这个问题来看源码(我看的4 ...

  10. Python try&sol;except&sol;finally等

    Python try/except/finally等   x = 'abc' def fetcher(obj, index): return obj[index] fetcher(x, 4) 输出: ...