ActionScript简单实现Socket Tcp应用协议分析器
转自。。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应用协议分析器的更多相关文章
- Http,Socket,TCP/IP 协议简述
Http,Socket,TCP/IP 协议简述:https://blog.csdn.net/gordohu/article/details/54097841 TCP/IP协议,HTTP协议与webSo ...
- 简单聊聊HTTP/TCP/IP协议
经过几天的面试,有很多公司的面试官都会问到是否了解HTTP/TCP/IP协议? 一遇到这个问题,就一脸懵逼,虽然是计算机基层的东西,看来是必须得了解的,回到家之后,就查找了一些资料,整理了一篇博客,简 ...
- 简单使用SOCKET,TCP,UDP模式之间的通信
TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议,由IETF的RFC 793定义.在简化的计算机网络OSI模型中, ...
- 使用Beetle简单构建高性能Socket tcp应用
beetle是基于c#编写的高性能Socket tcp组件,它基于SocketAsyncEventArgs的实现并提供了发送队列和接收队列的支持,可以根据情况灵活地设置1-N个发送队列和接收队列.除了 ...
- socket、tcp/ip协议、udp协议
socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. socket起源于Un ...
- TCP/IP 协议介绍
转自http://blog.jobbole.com/104886/ 一.TCP/IP 协议介绍 在介绍 HTTP 协议之前,先简单说一下TCP/IP协议的相关内容.TCP/IP协议是分层的,从底层至应 ...
- 门面模式的典型应用 Socket 和 Http(post,get)、TCP/IP 协议的关系总结
门面模式的一个典型应用:Socket 套接字(Socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元.它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息: 连接使用的 ...
- TCP/IP协议学习(四) 基于C# Socket的Web服务器---静态资源处理
目录 1. C# Socket通讯 2. HTTP 解析引擎 3. 资源读取和返回 4. 服务器测试和代码下载 Web服务器是Web资源的宿主,它需要处理用户端浏览器的请求,并指定对应的Web资源返回 ...
- TCP/IP协议学习(五) 基于C# Socket的C/S模型
TCP/IP协议作为现代网络通讯的基石,内容包罗万象,直接去理解理论是比较困难的:然而通过实践先理解网络通讯的理解,在反过来理解学习TCP/IP协议栈就相对简单很多.C#通过提供的Socket API ...
随机推荐
- 认识xml
什么是 XML? XML 指可扩展标记语言(EXtensible Markup Language) XML 是一种标记语言,很类似 HTML XML 的设计宗旨是传输数据,而非显示数据 XML 标签没 ...
- 我的Android进阶之旅------>Android服务的生命周期回调方法
先引用一段官网上的文字 ======================================================================================== ...
- weblogic8.1在myeclipse中启动正常,在单独的weblogic中无法正常启动的解决方案.
应用程序服务器weblogic8.1.5,项目在myeclipse中启动正常,在单独的服务器中启动就报错了.错误如下图: 经过观察,发现在myeclipse中设置了以下的jar包.估计是这个问题引起的 ...
- 【十】注入框架RoboGuice使用:(Your First Testcase)
上一篇我们简单的介绍了一下RoboGuice的使用([九]注入框架RoboGuice使用:(Your First Injected Service and BroadcastReceiver)),今天 ...
- 解决 jsp:include 引用文件时出现乱码的问题
阐述问题前,先来看一下下面这张图片左侧iframe中的乱码页面: 这个就是让我纠结好一阵子的乱码截图: 这个乱码页面中是使用了<jsp:include>引用标签后出现了这个问题: 源码截图 ...
- ORACLE物理存储结构
1.查看数据库实例基本信息: SQL> SELECT DBID,NAME,CREATED,LOG_MODE,OPEN_MODE,FORCE_LOGGING,CURRENT_SCN,FLASHBA ...
- 安装Php时候报错信息:virtual memory exhausted: Cannot allocate memory (不能分配内存)
原因是fileinfo这个函数在编译时非常消耗内存,而系统内存又不够了,所以才会出现此问题. 网上找了方法: 1,关闭其他占用大内存的进程. 2,在编译是添加参数 --disable-fileinfo
- WPS页面设置
以前使用WPS的时候遇到一些问题: 比如我输入一个英文的时候它总是自动的给我首字母大写,但是某些情况下我不想这样: 从VS中复制代码的时候不希望他吧那些颜色复制下来: 还有我输入1回车后它自动给我输入 ...
- Android 轮询之 Service + AlarmManager+Thread (转)
android中涉及到将服务器中数据变化信息通知用户一般有两种办法,推送和轮询. 消息推送是服务端主动发消息给客户端,因为第一时间知道数据发生变化的是服务器自己,所以推送的优势是实时性高.但服务器主动 ...
- CodeForces 698A - Vacations (Codeforces Round #363 (Div. 2))
要么去体育馆,要么去比赛,要么闲在家里 给出每一天体育馆和比赛的有无情况,要求连续两天不能去同一个地方 问最少闲几天 DP方程很容易看出 dp(第i天能去的地方) = min(dp(第i-1天的三种情 ...