Flex如何使用UDP传输

来源:互联网 发布:corethink php版本 编辑:程序博客网 时间:2024/05/16 00:49

 

最近项目需要做了一个UDP文件传输的例子,客户端与客户端的P2P连接需要服务器的协助,这里就没贴代码了。

最近项目需要做了一个UDP文件传输的例子,客户端与客户端的P2P连接需要服务器的协助,这里就没贴代码了。让人很郁闷的是FLEX中没有办法操 作多线程,在网上找了一些例子好像都是用Timer实现的伪多线程,一方面TCP SOCKET 实现不了P2P,另一方面UDP SOCKET没有异步传输真叫人很头痛,期待Adobe可以开放更多的操作了


 

ObjectA.as代码

 

 package com.UDP

{

 import com.UDP.UDPEvent;
 import flash.display.Sprite;
 import flash.events.DatagramSocketDataEvent;
 import flash.events.Event;
 import flash.events.EventDispatcher;
 import flash.events.InvokeEvent;
 import flash.filesystem.File;
 import flash.filesystem.FileMode;
 import flash.filesystem.FileStream;
 import flash.net.DatagramSocket;
 import flash.net.Socket;
 import flash.net.registerClassAlias;
 import flash.utils.ByteArray;

 


 /**

  * E2即时通UDP文件传输发起方

  */

 public class ObjectA  extends EventDispatcher
 {
  private var _sock:DatagramSocket;
  private var _toip:String;
  private var _toport:uint;

 

  //数据包大小,1024bytes

  private const _packsize:uint = 1019;
  private var _packnum:uint = 0;
  private var data:ByteArray= new ByteArray();

 

  /**

   * obj发送对象,sock本机socket,toip对方IP,toport对方端口

   */

  public function ObjectA(sock:DatagramSocket,toip:String,toport:int)

  {

   _toip = toip;
   _toport = toport;
   _sock = sock;
   _sock.addEventListener(DatagramSocketDataEvent.DATA,dataReceive);
   _sock.receive();
  }

 

  /**

   * 格式化传输数据并告知B要开始传输,命令头为1

   */

  public function invokeB(obj:Object):void{
   data.writeObject(obj);
   //重置数据读取流,注意读取操作并不改变data所包含内容
   data.position = 0;
   trace(data.bytesAvailable);
   _packnum = data.bytesAvailable/_packsize;
   if(data.bytesAvailable%_packsize>0){
    _packnum++;
   }

   

   var buffer:ByteArray = new ByteArray();
   buffer.writeByte(1);
   buffer.writeUnsignedInt(_packnum);
   buffer.position = 0;
   _sock.send(buffer,0,buffer.bytesAvailable,_toip,_toport);
  }

 

  /**

   * 控制通道SOCKET接收数据事件处理

   */

  private function dataReceive(e:DatagramSocketDataEvent):void{
   var cmd:int = e.data.readByte();
   var ret:ByteArray = new ByteArray();
   switch(cmd){
    case 1:  //接受传输文件请求
     transferOnce();
     break;
    case 2:
     var buffer:ByteArray = new ByteArray();
     while(e.data.bytesAvailable){
      var packnum:uint = e.data.readUnsignedInt();
      //reset package position and read length
      this.data.position = (packnum*_packsize);
      var vlen:uint = _packsize;
      if(packnum==_packnum){
       vlen = this.data.bytesAvailable;
      }

     

      //写入数据命令头0
      buffer.writeByte(0);
      //写入长度为packnum的包头
      buffer.writeUnsignedInt(packnum);
      //写入长度为vlen的包内容
      var n:int = 0;
      for(var j:uint=0;j<vlen;j++){
       n = this.data.readByte();
       buffer.writeByte(n);

      }

     

      //send package to client B
      buffer.position = 0;
      _sock.send(buffer,0,buffer.bytesAvailable,_toip,_toport);
      buffer.clear();
     }

     //发送成功,发送结束标志,命令头为2

     buffer.writeByte(2);
     buffer.position = 0;
     _sock.send(buffer,0,buffer.bytesAvailable,_toip,_toport);
     break;
    case 3:
     this.dispatchEvent(new UDPEvent(UDPEvent.Complete));
     this.finalize();
     break;
    default:
     break;
   }
  }

  /**

   * 分片传输所有数据包,命令头为0

   */

  private function transferOnce():void{
   var buffer:ByteArray = new ByteArray();
   var i:int = 0;
   var n:int = 0;

  

   while(this.data.bytesAvailable){
    i++;
    var vlen:uint = _packsize;
    if(vlen>this.data.bytesAvailable){
     vlen = data.bytesAvailable;
    }

   

    //写入数据命令头0
    buffer.writeByte(0);
    //写入长度为i的包头
    buffer.writeUnsignedInt(i);
    //写入长度为vlen的包内容
    for(var j:uint=0;j<vlen;j++){
     n = this.data.readByte();
     buffer.writeByte(n);

    }

    var udpevent:UDPEvent = new UDPEvent(UDPEvent.Process,i/_packnum);
    this.dispatchEvent(udpevent);
    buffer.position = 0;
    _sock.send(buffer,0,buffer.bytesAvailable,_toip,_toport);
    buffer.clear();
   }

   //发送成功,发送结束标志,命令头为2

   buffer.writeByte(2);
   buffer.position = 0;
   _sock.send(buffer,0,buffer.bytesAvailable,_toip,_toport);

  }
  /**

   * 释放资源

   */
  private function finalize():void{
   this._packnum=0;
   this.data.clear();
  }
 }

}
 

原创粉丝点击