twzheng's cppblog

『站在风口浪尖紧握住鼠标旋转!』 http://www.cnblogs.com/twzheng

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  136 随笔 :: 78 文章 :: 353 评论 :: 0 Trackbacks
[转] ActionScript3.0 Socket

介绍:Socket 连接允许Flash Player通过特定的网络端口来发送和加载数据。Socket和server连接的最大的不同点是Socket连接在数据传输完毕之后是不会自动的关闭。
    在一个socket连接建立之后,这个连接就会一直处于打开状态,除非客户端或者服务器段显式的关闭它。基于此,socket允许一种特殊的数据传输方式,叫做data push,这种凡是允许客户段的Flash Player没有发送请求的时候,服务器可以在任何时候把数据传送到客户端播放器。
    Socket连接典型的应用就是创建多用户的应用程序,一中此类应用程序比如在线聊天室。聊天室由一个中心服务器和一些连接到服务器的Flash Player客户端组成。每次客户端的.swf文件发送一条消息到服务器,服务器判断那个客户端应该接受这个消息,然后就把这条消息从打开的连接上发送给合适的用户。这种情况下,接受消息的客户并没有请求接受一个消息,但是这个消息从服务器端发送出去了。当一个客户关闭连接的时候,服务器通知所有的客户有人离开的聊天系统。
    Flash Player可以发送两种socket连接到socket服务器,两种方式有相同的行为和操作,但是也有细小的不同。第一种是XML socket连接,这种方式和之前的Player版本中的XMLSocket类似,对Flash 9来说binary socket是全新的方式。
    我们通过flash.net.XMLSocket和flash.net.Socket两个类来建立socket连接。
    XML socket 以文本为传输方式,客户端和服务器通过包含数据的XML包来交换数据,通过分析XML包的内容来执行动作。
    Binary socket是ActionScript3.0的新东西,这种方式允许我们通过原始链接来传递二进制信息。Binary socket比XML socket要更加的高效,因为binary socket需要了低级的类型信息,这种方式更加强大,因为我们可以连接到更加宽广的socket服务器上。比如,binary socket允许我们连接到邮件服务器(POP3,SMTP,IMAP),新闻服务器(通过NNTP),聊天服务器,甚至是桌面共享和远程桌面通过连接VNC服务器。
    不管什么样的socket连接类型,他们都是异步执行的,这就意味着我们不能通过socket链接来获得数据知道我们被通知数据加载结束,所有的数据加载都必须通过事件处理来自动执行。当我们需要在程序运行的时候通过加载一些数据来使它继续运行下去的时候就需要同步的数据加载,这种方式比较容易编写程序,但是不够高效。通过这章的学习你会更多学到如何通过异步的方式来加载数据。
连接到一个Socket Server
问题:我们想建立一个到socket服务器的连接
解决:Sokect.connect()或者XMLSocket.connect()方法。
讨论:在我们连接到一个服务器之前,有两个重要的信息我们必须知道,第一个是服务器的域名或者ip地址,第二个是我们连接的端口。
    不论我们用的是那种连接方式,连接的处理过程完全一样,两个连接类都有一个connect方法,这个方法接受两个参数:
    Host:这个参数是一个字符串,表示我们需要连接的服务器的地址,可以是一个域名,比如www.example.com或者一段ip地址。当我们连接的就是本服务器的时候,直接传递个null。
    Port:一个整形类型的参数指定了我们连接到的服务器的端口号码。端口号码最小必须是1024,除非有配置文件说明端口号码可以小于1024。 
    由于在Flash中socket编程是异步这样的事实,因此connect方法是不会等到socket调用返回就会执行connect语句的下面一条语句的,如果你想在连接完全建立之前做一些和socket的交互工作,你的代码就会遇到一些错误。
    比较正确的做法就是在我们调用connect方法之前,我们添加一些侦听事件到sokect对象,当连接成功建立的时候,会分发一个connect事件,这个事件告诉我们连接已经建立好了,我们可以开始和socket交互了。
    如果我们想链接到本地的2900端口上的代码看起来如下:
package {
 import flash.display.Sprite;
 import flash.events.*;
 import flash.net.Socket;
 public class SocketExample extends Sprite {
    private var socket:Socket;
    public function SocketExample( ) {
      socket = new Socket( );
      // Add an event listener to be notified when the connection
      // is made
      socket.addEventListener( Event.CONNECT, onConnect );
      // Connect to the server
      socket.connect( "localhost", 2900 );
    }
    private function onConnect( event:Event ):void {
      trace( "The socket is now connected..." ); 
    }
 }
}
    如果我们想通过XMLSocket来建立连接,基本的代码完全一样我们只需要用XMLSocket来代替Socket类。
    如果连接失败,会产生运行时错误,或者抛出ioError或者securityErrot异常,来通知连接没有完全成功的建立。更多的关于异常事件参考错误处理章节
    记住,在我们连接到一个服务器的时候,下边的Flash Player sandbox要遵守:
1.       swf文件必须和主机在相同的域当中
2.       跨域的swf文件是不能访问本地服务器的
3.       本地非信任的swf文件不能访问任何的网络资源
4.       如果允许跨域并且端口号低于1024的访问时,必须配置跨域配置文件
任何违反安全砂箱的操作比如连接到不信任域或者很小的端口的操作都会引发securityError事件,这些问题可以通过编写配置文件来解决。为了在Socket和XMLSocket中使用跨域的配置文件,我们必须加载配置文件:
Security.loadPolicyFile("http://www.rightactionscript.com/crossdomain.xml");
在我们编辑配置文件时,我们不应该仅仅指定受信任的域,还应该有受信任的端口,如果你没有指定任何的端口,Flash Player将默认80是唯一受信任的端口,你可以通过在port属性的值后边添加一个逗号来制定其它的受信任的端口号码,如下:
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
   <allow-access-from domain="*" to-ports="80,110" />
</cross-domain-policy>
发送数据
问题:我们想把数据传送到socket服务器
解决:对Socket对象来说,使用write方法(wirteByte(),writeUTFBytes()),来把数据写入缓冲区,然后调用flush()方法把数据刷新到输出流。对XMLSocket对象,使用send方法。
讨论:Socket和XMLSocket定义不同的api来发送数据到服务器,让我们先来了解下API.
    当我们向使用Socket对象来发送数据的时候,首先必须把数据写到缓冲区,Socket类定义了一些用来写数据的方法.每个方法都用来写不同类型的数据.这些方法有: writeBoolean( ), writeByte( ), writeBytes( ), writeDouble( ), writeFloat( ), writeInt( ), writeMultiByte( ), writeObject( ), writeShort( ), write- UnsignedInt( ), writeUTF( ), and writeUTFBytes( ).大部分这些方法接受的参数通过方法的名字已经暗示了.
    在我们使用的时候到底使用那个方法完全取决于我们希望发送什么样的数据到服务器,使用Socket类的时候,你可以完全通过ActionScript来把数据写到Telent或者POP mail服务器.两种协议都期望ASCII文本命令,比如,在我们连接到一个POP服务器之后,我们就可以通过USER命令来指定一个用户,下边的例子就是向Socket服务器写这样一个命令的例子:
// POP servers expect a newline (\n) to execute the preceding command.
socket.writeUTFBytes("USER exampleUsername\n");
   把数据写入Socket对象并不意味着就已经传给服务器了,调用每个write方法都会把数据添加到Socket对象上,比如,下边的例子中我们把四个字节的数据添加到Socket对象,但是他们中的任何一个都没有被发送到服务器:
socket.writeByte(1);
socket.writeByte(5);
socket.writeByte(4);
socket.writeByte(8);
   当我们向把Socket中的数据传送到服务器的时候,调用Socket对象的flush()
方法.
   XMLSocket对象基本上和Socket对象有同样的Api接口,通过调用send()方法来把数据传送到服务器.send方法接受任何类型的参数,它会把这个参数转换成string类型,然后传送到服务器.一般情况下这个参数是XML对象或者一个字符串里边包含结构化的XML数据:
xmlSocket.send(xml);
    然而,精确的数据格式完全依赖于服务器段的期望格式,如果服务器期望格式化的XML数据,那么你就必须传递格式化的XML数据过去,如果服务器期望URL编码的数据,那么你就必须传递这样的数据过去.
接受数据
To be continuing……


[源] http://tb.blog.csdn.net/TrackBack.aspx?PostId=1688278

posted on 2007-07-19 19:31 谭文政 阅读(785) 评论(0)  编辑 收藏 引用 所属分类: 技术·业界

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理