当前位置:首页 > 设计在线 > 平面动画 > Flash > Flash中的P2P通信技巧(AS-Java-AS)上

Flash中的P2P通信技巧(AS-Java-AS)上

点击次数:35 次 发布日期:2008-11-21 23:29:46 作者:源代码网
源代码网推荐

众所周知Flash的功能比较强大,但是有两个功能到目前为止始终无法实现

是swf的点对点连接
是swf读写操作文件
别想了,靠Flash本身是不可能的,虽然有传说中的MMSave();等一些隐藏函数,但是毕竟这些未公开的函数了解的人并不多,用起来也不方便。
那么究竟有没有其他办法可以扶助实现呢?答案当然是肯定的。在这里我们需要请出当前最热的两门名副其实的编程语言C++/Java,靠他们来实现你要实现的功能吧。

在这里我用Java举例。

首先我们必须了解 AS如何让Java做事?对于双方来讲唯一应用性最高的途径就是Socket了。
AS1->XMLSocket->send()->Java.Socket->InputStream
AS2->XMLSocket->send()->Java.Socket->InputStream
AS3->Socket->writh()->flush()->Java.Socket->InputStream
as1&2只支持以字符串形式发送socket,而as3支持真正意义上的流,在这里为了兼容和教学简单,我均以字符串形式来实现相互间的通信。

1->AS与Java最基本的通信

1.1 简单Java服务器

首先我们来做最简单的单线程Java服务器

import java.io.*;
import java.net.*;
public class Server extends ServerSocket{
    //服务端口号常量(as要求必须大于1024,小于65535)
    private static final int SERVER_PORT = 10086;
    //申明流的空间
    private Socket client;
    private BufferedReader in;
    private PrintWriter out;
    private String src;
    //构造函数
    public Server() throws IOException{
        super(SERVER_PORT);
        //监听连接,初始流在进来后读取前,和写入后发送前所存放的空间
        Socket socket = accept();
        in = new BufferedReader(new InputStreamReader(client.getInputStream()));
        out = new PrintWriter(client.getOutputStream(),true);
        //循环等待读取信息
        while(true){
            //读取行信息,注意是以换行符结束的
            src = in.readLine();
            //如果发送"close",就跳出循环(断开连接)
            if(src.equals("close")){
                break;
            }
            //在收到的信息前加是标识并发回(注意结尾加"",这是as的XMLSocket读入每条信息的条件.as3的Socket不需要)
            out.println("rev: "+src+"");
            //以上out.println("xx")相当于out.write("xx");out.flush();的执行效果
            System.out.println("msg is "+src)
        }
        //关闭连接
        close();
    }
       
    //入口函数...
    public static void main (String[] args) throws IOException{
        new Server();   
    }
}

这样一个Java的服务器就建好了,Java是同步的事件的驱动是等待的,这个AS是不同的,所以方法对与as区别还是比较大的,具体功能已经注释的非常清楚。至于具体Java的特性我不是专业的,为了对读者负责我就不做详细介绍了,有兴趣的朋友可以查阅Java相关书籍。
接下来呢就是AS的访问了:
1.2 AS1 与 Java 通信

Action Script 1

var SERVER_PORT = 10086;
var SERVER_IP = "127.0.0.1";
var conn = new XMLSocket();
conn.connect(SERVER_IP,SERVER_PORT);
conn.onConnect = socketConnect;
conn.onData = socketData;
function socketConnect(success){
    trace("connect"+success);
    if(success){
        this.send("hello world ");
    }
}
function socketData(src){
    trace(src);
}

接触了相对生疏的Java后现在回到AS,感觉就是爽,嘿嘿
前三行定义了三个变量,由于as1没有强制类型,所以千万别加上类型修饰符啊,反而会出错,请注意。
conn.connect(SERVER_IP,SERVER_PORT);连接到socket的服务器。
如果连接成功 Java中的 ServerSocket.accept();会返回一个对象,并向下执行。
as的连接成功呢则触发了socketConnect(success)的事件,并且把true的参数传如函数。当然连不到就是false了。
成功后就会发送一个"hello world "的字符串," "是回车符,因为Java里我用的是readLine();所以需要看到行的结束。
当有数据进来的时候呢就会出发socketData函数了,这里把信息输出。
好了用as1的朋友到此已经成功与Java程序通讯了。

1.3 AS2 与 Java 通信

Action Script 2

var SERVER_PORT:Number = 10086;
var SERVER_IP:String = "127.0.0.1";
var conn:XMLSocket = new XMLSocket();
conn.connect(SERVER_IP,SERVER_PORT);
conn.onConnect = socketConnect;
conn.onData = socketData;
function socketConnect(success:Boolean){
    trace("connect"+success);
    if(success){
        this.send("hello world ");
    }
}
function socketData(src:String){
    trace(src);
}

以上是fla版,和as1唯一的区别就是有类型定义,这样做无论是时间执行效率还是空间执行效率都会有明显提高。
接下去看看真正的Action Script 2代码,将以下代码保存成Socket.as文件,和fla文件放在一起。

class Socket extends XMLSocket{
    public function Socket(){
        super();
    }
    public function onConnect(success:Boolean){
        trace("connect"+success);
        if (success){
            this.send("hello world ");
        }
    }
    public function onData(src:String){
        trace(src);
    }
}

fla里在帧上写

var SERVER_PORT:Number = 10086;
var SERVER_IP:String = "127.0.0.1";
var conn:Socket = new Socket();
conn.connect(SERVER_IP,SERVER_PORT);

这才是真正的as2,当然你可以更好的修改Socket,让他符合Server的要求,比如在类里加上一个常量,并写入符合Server要求的方法。

public var msg:String = "";
public function write(src){
    msg += src;
}
public function flush(){
    this.send(msg+" ");
    msg = "";
}

这样在fla里发送的方式就改为

conn.write("hello world");
conn.flush();

这样是不是又规范又符合Java的要求了呢?我只是举是一个简单例子,你可以按要求自己再修改

1.4 AS3 与 Java 通信

Action Script 3
最后是传说中的as3了,这里我们用Socket中的writeUTFBytes();来写字符串。首先来看fla版的

var SERVER_PORT:Number = 10086;
var SERVER_IP:String = "127.0.0.1";
var conn:Socket = new Socket(SERVER_IP,SERVER_PORT);
conn.addEventListener("connect",socketConnect);
conn.addEventListener("socketData",socketData);
function socketConnect(event:Event){
    event.target.writeUTFBytes("hello world");
    event.target.writeByte(10);
    event.target.flush();
}
function socketData(event:ProgressEvent){
    trace(event.target.readUTFBytes(event.target.bytesAvailable));
}

看看这个fla版本的是不是在代码上思路更加清晰呢?所有事件已经全部改为监听的方式,并且所有事件将把事件作为参数传入函数。
bytesAvailable为字节长度,而readUTFBytes的参数是从当前指向的位置读取到参数位置,这样写就是读完。
在as2里,如果在事件触发的函数里写this指向的是触发事件的实例,而as3永远指向所在类的实力,触发事件的实例被记录在传入事件参数的target对象中。
as3更加注重的是oop,在fla里已经体现出来了。接下来就来看看DocmentClass的方法

package{class Run{
    private var SERVER_PORT:Number = 10086;
    private var SERVER_IP:String = "127.0.0.1";
    public function Run(){
        //在这里写代码并在flash里设置该类为文档类,和直接写上帧上其实没有区别,入口函数
        new ClientSocket(SERVER_IP,SERVER_PORT);
    }
}}

当然还有一个ClientSocket.as的文件放这个socket客户端类

package {
    import flash.net.Socket;
    import flash.events.ProgressEvent;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    public class ClientSocket extends Socket {
        public function ClientSocket(ip:String,port:uint) {
            super(ip,port);
            addEventListener("cennect",socketConnect);
            addEventListener("socketData",socketData);
            addEventListener("ioError",ioError);
        }
        public function send(src:String) {
            writeUTFBytes(src);
            writeByte(10);
            flush();
        }
        private function socketConnect(event:Event) {
            send("hello world");
        }
        private function socketData(event:ProgressEvent) {
            trace(readUTFBytes(bytesAvailable));
        }
        private function ioError(event:IOErrorEvent) {
            trace("connect error");
        }
    }
}

入口函数创建了一个客户端的对象,而具体的类的内部构造如上代码所示:
首先创建父类构造函数,再为自己添加监听,当连接时执行socketConnect();发送字符串,注意writeByte(10)是换行符。
在as3的socket类里还有其他的事件,这里因为教学原因所以没有过多的举例,相关可以查阅socket的帮助
close  在服务器关闭套接字连接时调度。
connect  在建立网络连接后调度。(这个监听在教程里已经实现)
deactivate  Flash Player 失去操作系统焦点并变为非活动状态时调度。
ioError  在出现输入/输出错误并导致发送或加载操作失败时调度。(以前是在onConnect传入false,而这里是直接引发ioError事件,更规范)
securityError  若对 Socket.connect() 的调用尝试连接到调用方安全沙箱外部的服务器或端口号低于 1024 的端口,则进行调度。
socketData  在套接字接收到数据后调度。 (这个监听在教程里已经实现)

 

源代码网供稿.
网友评论 (0)
会员中心
设计在线
本站推荐
设计在线之精华