AIR Socket服务器的实现

4 篇文章 0 订阅
    前两天,同事问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;
}
}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值