前两天,同事问Flash是否能为实现监测本地端口(socket)?这个问题之前还真没认真了解过,只知道flash有个Socket和XMLSocket来实现连接到Socket服务器,而且flash无法直接访问到本地文件。在网上搜索了下,发现flash.net包中有个ServerSocket类,在API文档是这样描述的:

     1、 ServerSocket 类允许代码充当传输控制协议 (TCP) 连接的服务器。
     2、 AIR 配置文件支持: 所有桌面操作系统、iOS(自 AIR 3.8 起)和Android(自 AIR 3.8 起)均支持此功能。AIR for TV 设备不支持此功能。您可以使用  ServerSocket.isSupported  属性在运行时测试是否受支持。
     3、 TCP 服务器侦听来自远程客户端的传入连接。当客户端尝试连接时,ServerSocket 将调度  connect  事件。为此事件调度的 ServerSocketConnectEvent 对象提供了表示服务器和客户端之间 TCP 连接的 Socket 对象。将此 Socket 对象用于与连接的客户端的后续通信。如果需要,您可以从 Socket 对象获取客户端地址和端口。
     4、 要使 ServerSocket 对象进入侦听状态,请调用  listen()  方法。在侦听状态下,每当使用 TCP 协议的客户端尝试连接到绑定地址和端口时,服务器 Socket 对象将调度  connect  事件。在调用  close()  方法之前,ServerSocket 对象将继续侦听其他连接。
     5、 ServerSocket 类仅可在 Adobe AIR 应用程序和应用程序安全沙箱中使用。
     根据描述,Flash是可以实现的,但只能用AIR来实现,因为AIR 具有操作系统的能力。     
    下面是服务端和客户端连接的例子:

    服务端ServerSocket的代码:
    
  
package
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.ProgressEvent;
import flash.events.ServerSocketConnectEvent;
import flash.net.ServerSocket;
import flash.net.Socket;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFieldType;
public class ServerSocketExample extends Sprite
{
private var ipLblTf:TextField;
private var ipTf:TextField; //监听ip输入框
private var portLblTf:TextField;
private var portTf:TextField;//监听端口输入框、
private var connectBtn:Sprite;
private var serverSocket:ServerSocket;
private var logTf:TextField;
private var socketList:Vector.<Socket>;
private var input:TextField;
private var sendBtn:Button;
public function ServerSocketExample()
{
this.stage.align = StageAlign.LEFT;
this.stage.scaleMode = StageScaleMode.NO_SCALE;
initUI();
socketList = new Vector.<Socket>();
}
private function initUI():void
{
ipLblTf = createLable("侦听本地的IP地址:",0,0);
portLblTf = createLable("侦听的端口:",0,40);
ipTf = createInputText(100,30,150,0,"127.0.0.1");
portTf = createInputText(100,30,150,40,"0");
connectBtn = new Button("绑定",100,30);
connectBtn.y = 100;
logTf = createInputText(254,100,0,150,"");
logTf.type = TextFieldType.DYNAMIC;
input = createInputText(195,30,logTf.x,logTf.y+logTf.height+10,"");
sendBtn = new Button("发送",50,30);
sendBtn.x = input.x+input.width+10;
sendBtn.y = input.y;
this.addChild(ipLblTf);
this.addChild(portLblTf);
this.addChild(ipTf);
this.addChild(portTf);
this.addChild(connectBtn);
this.addChild(logTf);
this.addChild(input);
this.addChild(sendBtn);
connectBtn.addEventListener(MouseEvent.CLICK,onConnectClick);
sendBtn.addEventListener(MouseEvent.CLICK,onSendClick);
}
private function onConnectClick(e:MouseEvent):void
{
/**套接字是否为null或绑定到本地地址和端口*/
if( serverSocket == null ||serverSocket.bound )
{
/**关闭套接字并停止侦听连接*/
if(serverSocket != null)
serverSocket.close();
serverSocket = new ServerSocket();
}
/**将此套接字绑定到指定的本地地址和端口。*/
try
{
trace("侦听ip:"+ipTf.text,"端口:"+portTf.text);
serverSocket.bind( parseInt( portTf.text ), ipTf.text );
}
catch(error:Error)
{
trace(error);
trace(error.message);
log(error.message);
}
/**远程套接字Socket连接到ServerSocket时调度*/
serverSocket.addEventListener( ServerSocketConnectEvent.CONNECT, onServerSocketConnect );
/**侦听绑定的 IP 地址和端口上的 TCP 连接*/
serverSocket.listen();
log("服务器正在侦听"+ipTf.text+"端口"+portTf.text);
}
/**
* 获得连接到该服务端的socket引用
* @param e
*
*/
private function onServerSocketConnect(e:ServerSocketConnectEvent):void
{
var socket:Socket = e.socket;
if(socket!=null)
{
socketList.push(socket);
socket.addEventListener( ProgressEvent.SOCKET_DATA, onClientSocketData );
socket.addEventListener(Event.CLOSE,onClientSocketClose);
log( "客户端连接地址 " + socket.remoteAddress + ":" + socket.remotePort );
}
}
/**
* 接收socket端发送的数据
* @param e
*
*/
private function onClientSocketData(e:ProgressEvent):void
{
var socket:Socket = e.currentTarget as Socket;
if(socket !=null && socket.bytesAvailable)
{
log( "接收客户端" + socket.remoteAddress + ":" + socket.remotePort+"的消息:"+socket.readUTF());
}
}
private function onClientSocketClose(e:Event):void
{
var socket:Socket = e.currentTarget as Socket;
removeSocket(socket);
}
private function onSendClick(e:MouseEvent):void
{
sendMessage(input.text);
}
/**
* 移除已断开连接的socket引用
* @param socket
*
*/
private function removeSocket(socket:Socket):void
{
if(socket != null)
{
var index:int = socketList.indexOf(socket);
if(index >-1)
{
socketList.splice(index,1);
}
socket.removeEventListener( ProgressEvent.SOCKET_DATA, onClientSocketData );
socket.removeEventListener(Event.CLOSE,onClientSocketClose);
log( "客户端" + socket.remoteAddress + ":" + socket.remotePort+"已关闭");
}
}
/**
*发送消息到连接到该服务端的socket连接
* @param msg 消息
*
*/
private function sendMessage(msg:String):void
{
try
{
var flag:Boolean = false;
for each(var so:Socket in socketList)
{
if(so != null && so.connected)
{
so.writeUTF(msg);
so.flush();
log( "已发送消息到: " + so.remoteAddress + ":" + so.remotePort );
flag = true;
}
}
if(!flag)
{
log("没有Socket连接");
}
}
catch ( error:Error )
{
log( error.message );
}
}
private function log(text:String):void
{
logTf.appendText( text + "\n" );
logTf.scrollV = logTf.maxScrollV;
}
/**
* 创建标签
* @param lable
* @param x
* @param y
* @return
*
*/
private function createLable(lable:String,x:Number,y:Number):TextField
{
var tf:TextField = new TextField();
tf.autoSize = TextFieldAutoSize.LEFT;
tf.text = lable;
tf.x = x;
tf.y = y;
return tf;
}
/**
* 创建输入文本框
* @param width
* @param height
* @param x
* @param y
* @return
*
*/
private function createInputText(width:Number,height:Number,x:Number,y:Number,text:String):TextField
{
var inputTf:TextField = new TextField();
inputTf.width = width;
inputTf.height = height;
inputTf.border = true;
inputTf.type = TextFieldType.INPUT;
inputTf.text = text;
inputTf.x = x;
inputTf.y = y;
return inputTf;
}
}
}

客户端Socket的代码:
   
package
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.MouseEvent;
import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
import flash.net.Socket;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFieldType;
public class SocketExamplet extends Sprite
{
private var ipLblTf:TextField;
private var ipTf:TextField; //监听ip输入框
private var portLblTf:TextField;
private var portTf:TextField;//监听端口输入框、
private var connectBtn:Sprite;
private var socket:Socket;
private var logTf:TextField;
private var input:TextField;
private var sendBtn:Button;
public function SocketExamplet()
{
this.stage.align = StageAlign.LEFT;
this.stage.scaleMode = StageScaleMode.NO_SCALE;
initUI();
}
private function initUI():void
{
ipLblTf = createLable("侦听本地的IP地址:",0,0);
portLblTf = createLable("侦听的端口:",0,40);
ipTf = createInputText(100,30,150,0,"127.0.0.1");
portTf = createInputText(100,30,150,40,"0");
connectBtn = new Button("绑定",100,30);
connectBtn.y = 100;
logTf = createInputText(254,100,0,150,"");
logTf.type = TextFieldType.DYNAMIC;
input = createInputText(195,30,logTf.x,logTf.y+logTf.height+10,"");
sendBtn = new Button("发送",50,30);
sendBtn.x = input.x+input.width+10;
sendBtn.y = input.y;
this.addChild(ipLblTf);
this.addChild(portLblTf);
this.addChild(ipTf);
this.addChild(portTf);
this.addChild(connectBtn);
this.addChild(logTf);
this.addChild(input);
this.addChild(sendBtn);
connectBtn.addEventListener(MouseEvent.CLICK,onConnectClick);
sendBtn.addEventListener(MouseEvent.CLICK,onSendClick);
}
private function onConnectClick(e:MouseEvent):void
{
socket = new Socket();
try
{
/**连接事件侦听,在建立网络连接后调度,仅在服务器关闭连接时调度 close 事件;
* 在调用 Socket.close() 方法时不调度该事件。
* */
socket.addEventListener(Event.CONNECT,onConnect);
/**获得socket数据事件侦听,在套接字接收到数据后调度*/
socket.addEventListener(ProgressEvent.SOCKET_DATA,onSocketData);
/**关闭socket连接事件侦听*/
socket.addEventListener(Event.CLOSE,onClose);
/**
* 若对 Socket.connect() 的调用尝试连接到调用方的安全沙箱禁止的服务器或低于 1024 的端口,
* 且不存在允许进行此类连接的套接字策略文件,则进行调度。
* */
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR,onSecurityError);//
socket.addEventListener(IOErrorEvent.IO_ERROR,onIOError);
socket.connect(ipTf.text,parseInt(portTf.text));
}
catch(error:Error)
{
log(error.message);
}
}
private function onSendClick(e:MouseEvent):void
{
socket.writeUTF(input.text);
socket.flush();
log( "已发送消息到服务端: " + socket.remoteAddress + ":" + socket.remotePort );
}
private function onConnect(e:Event):void
{
log("已连接到远程服务器"+ipTf.text+"端口"+portTf.text);
}
private function onSocketData(e:ProgressEvent):void
{
if(socket.bytesAvailable)
{
log("接收的数据:"+socket.readUTF());
}
}
private function onSecurityError(e:SecurityErrorEvent):void
{
log(e.text);
}
private function onIOError(e:IOErrorEvent):void
{
log(e.text);
}
private function onClose(e:Event):void
{
log("连接已关闭");
}
private function log(text:String):void
{
logTf.appendText( text + "\n" );
logTf.scrollV = logTf.maxScrollV;
}
/**
* 创建标签
* @param lable
* @param x
* @param y
* @return
*
*/
private function createLable(lable:String,x:Number,y:Number):TextField
{
var tf:TextField = new TextField();
tf.autoSize = TextFieldAutoSize.LEFT;
tf.text = lable;
tf.x = x;
tf.y = y;
return tf;
}
/**
* 创建输入文本框
* @param width
* @param height
* @param x
* @param y
* @return
*
*/
private function createInputText(width:Number,height:Number,x:Number,y:Number,text:String):TextField
{
var inputTf:TextField = new TextField();
inputTf.width = width;
inputTf.height = height;
inputTf.border = true;
inputTf.type = TextFieldType.INPUT;
inputTf.text = text;
inputTf.x = x;
inputTf.y = y;
return inputTf;
}
}
}

AIR Socket服务器的实现相关推荐

  1. [转|整理]翻译:使用.net3.5的缓存池和SocketAsyncEventArgs类创建socket服务器

    原文地址:http://www.cnblogs.com/onlytiancai/archive/2008/06/25/1229321.html http://www.cnblogs.com/killk ...

  2. php运行socket服务器,PHP_php简单socket服务器客户端代码实例,本篇文章分享一个简单的socket - phpStudy...

    php简单socket服务器客户端代码实例 本篇文章分享一个简单的socket示例,用php.实现一个接收输入字符串,处理并返回这个字符串到客户端的TCP服务. 产生一个 socket 服务端 /*文 ...

  3. ActionScript接收socket服务器发送来的数据

    原文地址:http://www.asp119.com/news/2009522181815_1.htm 从socket中接收数据的方法取决于你使用socket类型,Socket和XMLSocket都可 ...

  4. 210130阶段三socket服务器

    目录 一.学习的知识点 基于socket服务器 socket函数 bind函数 listen函数 accept函数 二.上课没有听懂或者没有理解的地方 三.当天学习的收获 一.学习的知识点 每个上网的 ...

  5. php后端如何搭建socket服务,从php做一个简单的socket服务器流程

    socket的中文名字称为套接字,这类物品就是说对TCP/iP的"封裝".实际中的互联网事实上只能四层罢了,从上至下分別是网络层.传输层.网络层.统计数据链路层.最常见的.com协 ...

  6. 以C#编写的Socket服务器的Android手机聊天室Demo

      内容摘要 1.程序架构    2.通信协议    3.服务器源代码    4.客户端源代码    5.运行效果 一.程序架构 在开发一个聊天室程序时,我们可以使用Socket.Remoting.W ...

  7. github开源推荐:SuperSocket, 可扩展的 Socket 服务器框架

    1.简介 SuperSocket 是一个轻量级, 跨平台而且可扩展的 .Net/Mono Socket 服务器程序框架.你无须了解如何使用 Socket, 如何维护 Socket 连接和 Socket ...

  8. SuperSocket 2.0 Preview1 发布,.NET Socket服务器框架

    今天,SuperSocket的作者发布了2.0版本的第一个预览版.SuperSocket 2.0 是一个经过全新设计的,第一个完全基于.NET Core的版本.作者正在积极尝试提供更简单易用的API的 ...

  9. php soecket服务器搭建_PHP socket 服务器框架集

    1.Swoole:重新定义PHP PHP语言的高性能网络通信框架,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,数据库连接池,AsyncTask,消息队列,毫秒定时 ...

最新文章

  1. centos7下监控流量、数据包占用最大的进程
  2. 自考第一章计算机基础知识,2018年自考计算机网络技术基础复习资料:第一章...
  3. unity 平移图片_Unity 两张背景的切换平移
  4. boost::math::acosh用法的测试程序
  5. rlm sql mysql.so_UBUUTU7.10上安装配置freeradius+mysql+rp-pppoe手记
  6. pythoncharm安装时出错误_python01:pycharm中安装包时所遇到的问题
  7. c# mysql 连接串_c# – 如何形成一个正确的MySQL连接字符串?
  8. android数据持久化框架,Android:数据持久化、Environment、SharedPreferences、内部存储internalStorage...
  9. 计算机视觉实战(八)直方图与傅里叶变换
  10. python使用redis做缓存_Python的Flask框架使用Redis做数据缓存的配置方法
  11. shader 反射 水面_大规模水面渲染
  12. 牛津高阶字典ld2_(离线)英语词典软件推荐
  13. python链家爬虫
  14. Go第八篇之包的使用
  15. 常见软件环境的配置、下载...
  16. 坚定信念,踏踏实实走好脚下的每一步!
  17. 年轻的艺术家们是如何通过NFT赚取百万美元的?
  18. maya2018放大字体及窗口
  19. JS基础 Set 用于存储任何类型的唯一值
  20. CDH集成了Kerberos后写入数据到HBase遇到的几个问题

热门文章

  1. oracle免费的环境,分享 5 个免费的在线 SQL 数据库环境
  2. 人事管理系统 c语言版
  3. 利用人工智能进行自动决策,将为我们带来更加智慧的路
  4. 让ElementUI Message消息提示每次只弹出一次
  5. 群智感知-MobiSys2012-论文简析:基于移动电话的参与式感知预测公交车的到站时间
  6. error 系统错误 错误码10007_干货分享:退款系统,看这篇就够了
  7. APP的案例分析-美团外卖
  8. linux set命令详解
  9. java oval xml 校验
  10. 使用DALI模块加速