Java数据报之失序和丢包.docx

上传人:b****5 文档编号:7823720 上传时间:2023-01-26 格式:DOCX 页数:11 大小:19.63KB
下载 相关 举报
Java数据报之失序和丢包.docx_第1页
第1页 / 共11页
Java数据报之失序和丢包.docx_第2页
第2页 / 共11页
Java数据报之失序和丢包.docx_第3页
第3页 / 共11页
Java数据报之失序和丢包.docx_第4页
第4页 / 共11页
Java数据报之失序和丢包.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

Java数据报之失序和丢包.docx

《Java数据报之失序和丢包.docx》由会员分享,可在线阅读,更多相关《Java数据报之失序和丢包.docx(11页珍藏版)》请在冰豆网上搜索。

Java数据报之失序和丢包.docx

Java数据报之失序和丢包

Java数据报之失序和丢包

  习惯了TCP编程,认为UDP可以包办这些问题是错误的。

一个UDP应用程序要承担可靠性方面的全部工作,包括报文的丢失、重复、时延、乱序以及连接失效等问题。

  通常我们在可靠性好,传输时延小的局域网上开发测试,一些问题不容易暴露,但在大型互联网上却会出现错误。

  UDP协议把递送的可靠性责任推到了上层即应用层,下面简单编写了几个类来专门处理两个问题:

乱序和丢包。

  四个类:

DataPacket类,PacketHeader类,PacketBody类,DataEntry类,位于同一个文件DataPacket.java中。

  DataPacket类相当于一个门面模式,提供给外部使用,通信数据也在这个类中处理。

  packagecom.skysoft.pcks;

  importjava.io.*;

  import.*;

  importjava.util.*;

  publicclass DataPacket{

  OutputStreamos;

  PacketHeaderheader;

  PacketBodybody;

  ArrayListal;

  publicstaticfinalintDataSwapSize=64532;

 /**

  *在接收数据报使用

  */

  publicDataPacket(){

  header=newPacketHeader();

  body=newPacketBody();

  al=newArrayList();

  }

 /**

  *在发送数据报时使用,它调用报文分割操作.

  *@paramfileString 硬盘文件

  */

  publicDataPacket(Stringfile){

  this();

  try{

  is=newFileInputStream(file);

  header.CalcHeaderInfo(is.available());

  this.madeBody();

  is.close();

  //this.Gereratedata();

  }

  catch(FileNotFoundExceptionex){

  ex.printStackTrace();

  }

  catch(IOExceptionex1){

  ex1.printStackTrace();

    }

 }

  /**

  *在发送数据报时使用,它调用报文分割操作.

  *@paramurlURLurl地址

  */

  publicDataPacket(URLurl){

  this();

  try{

  //is=url.openStream();

  URLConnectionconn=url.openConnection();

  is=conn.getInputStream();

  inttotal=conn.getContentLength();

  header.CalcHeaderInfo(total);

  this.madeBody();

  //System.out.println(total+":

"+total);

  is.close();

    }

  catch(IOExceptionex){

  ex.printStackTrace();

  }

  }

  /**

  *为发送构造分组,使用PackageHeader处理了报头格式,并为分组编序号.

  */

  privatevoidmadeBody(){

  al.clear();

  byte[]buffer;

  DataEntryde;

  for(inti=0;i< header.fragmentcounter;i++){

  try{

  ByteArrayOutputStreambos=newByteArrayOutputStream();

  //is.skip(i*body.BODY_BUFFER_SIZE);

  header.ArrageSort(i);

  de=newDataEntry(PacketBody.BODY_BUFFER_SIZE);

  de.setSn(i);

  de.setStreamsize(header.getStreamsize());

  de.setFragmentcounter(header.getFragmentcounter());

  if(header.isWTailFragment(i)){

  buffer=newbyte[header.getMinfragment()];

  is.read(buffer,0,buffer.length);

  header.setActByteSize(header.getMinfragment());

  de.setActByteSize(header.getMinfragment());

     }

     else{

     buffer=newbyte[body.BODY_BUFFER_SIZE];

     is.read(buffer,0,buffer.length);

     }

  //System.out.println("length-------"+i+""+body.getBody().length+""+header.getMinfragment());

  body.setBody(buffer);

  //System.out.println("length:

"+i+""+header.toString());

  bos.write(header.getByte(),0,header.HEADER_BUFFER_SIZE);

  bos.write(body.getBody(),0,body.getBody().length);

  de.setBytes(bos.toByteArray());

  al.add(de);

  }

  catch(IOExceptionex){

  ex.printStackTrace();

  }

   }

  }

  /**

  *为发送构造分组,没有考虑报头格式,也没有为分组编序号.

  */

  privatevoidmadeBody1(){

  al.clear();

  for(inti=0;i< header.fragmentcounter;i++){

  try{

  if(header.isWTailFragment(i))

  is.read(body.getBody(),i*body.BODY_BUFFER_SIZE,

  header.getMinfragment());

     else

  is.read(body.getBody(),i*body.BODY_BUFFER_SIZE,

  body.BODY_BUFFER_SIZE);

  ByteArrayOutputStreambos=newByteArrayOutputStream();

  bos.write(header.getByte(),0,header.HEADER_BUFFER_SIZE);

  bos.write(body.getBody(),header.HEADER_BUFFER_SIZE,

           body.getBody().length);

  al.add(bos);

   }

   catch(IOExceptionex){

     ex.printStackTrace();

     }

   }

   }

  /**

   *在接收到报文后,对此报文执行组装,并处理报文丢失和乱序情况.

   *@paramb1byte[]

   */

  publicvoidAdd(byte[]b1){

  byte[]buffer=(byte[])b1.clone();

    handlerText(buffer);

  DataEntryde=newDataEntry(buffer,header.getActByteSize());

  de.setSn(header.getSn());

  de.setStreamsize(header.getStreamsize());

  de.setFragmentcounter(header.getFragmentcounter());

  al.add(de);

  }

  privatevoidhandlerText(byte[]buffer){

  ByteArrayOutputStreambaos=newByteArrayOutputStream();

  baos.write(buffer,0,header.HEADER_BUFFER_SIZE);

  byte[]b=newbyte[header.HEADER_BUFFER_SIZE];

  System.arraycopy(buffer,0,b,0,b.length);

  ByteArrayInputStreambais=newByteArrayInputStream(baos.toByteArray());

  InputStreamReaderisr=newInputStreamReader(bais);

  BufferedReaderbr=newBufferedReader(isr);

  try{

    header=newPacketHeader(br.readLine());

  }

  catch(Exceptionex){

    ex.printStackTrace();

  }

   }

 

 privateStringcalFileSize(intsize){

  returnsize/1024+"K";

  }

  publicArrayListgetDataPackets(){

  returnal;

  }

  /**

  *是否接收完毕,通过序号是否等于最大段数来判断,这也许有问题,比如,正好是最后一个段丢失了,这样

  *这个包整个就丢失了.

  *@return

  */

  publicbooleanisFull(){

  returnthis.header.getSn()==this.header.getFragmentcounter()-1?

true:

false;

 }

  /**

  *判断是否只有一个段.

  *@return

  */

   publicbooleanisZero(){

  returnthis.header.getSn()==0?

true:

false;

   }

 /**

  *该函数执行报文组装,不考虑丢失的报文.

  *@return

  */

   privateByteArrayOutputStreamfetchDataPackets(){

   ByteArrayOutputStreambos=newByteArrayOutputStream();

   byte[]buffer=null;

   DataEntryde;

   for(inti=0;i<  al.size();i++){

     try{

     de=this.getSnData(i);

     buffer=de.getByte();

     if(header.getStreamsize()==de.getStreamsize()){

     bos.write(de.getByte(),header.HEADER_BUFFER_SIZE,de.getActByteSize());

     System.out.println(de.toString()+"--fetchDataPackets");

     }

    }

    catch(Exceptionex){

      ex.printStackTrace();

    }

  }

  returnbos;

  }

  /**

  *该函数执行报文组装,对于丢失的报文,写入空报文.

  *@returnByteArrayOutputStream

  */

  privateByteArrayOutputStreamfetchDataPackets_sn(){

  ByteArrayOutputStreambos=newByteArrayOutputStream();

  byte[]buffer;

  DataEntryde;

  for(inti=0;i<  header.getFragmentcounter();i++){

    try{

      de=this.getSnData(i);

      if(de==null){

      de=seachDeData(i);

      }

      buffer=de.getByte();

      //System.out.println(de.getSn()+":

"+i);

      //handlerText(buffer);

      //bos.write(buffer,header.HEADER_BUFFER_SIZE,

      //      buffer.length-header.HEADER_BUFFER_SIZE);

      if(header.getStreamsize()==de.getStreamsize()){

      bos.write(de.getByte(),header.HEADER_BUFFER_SIZE,

              de.getActByteSize());

      //System.out.println(de.toString());

    }

    }

    catch(Exceptionex){

      ex.printStackTrace();

    }

  }

  returnbos;

  }

  /**

  *对缓冲的数据包进行排序处理,即按顺序提取同一帧的数据,如果没有找到该序号的帧,则返回空值.

  *@paramsnint要找的帧序号.

  *@returnDataEntry

  */

  privateDataEntrygetSnData(intsn){

  DataEntryde=null;

  for(inti=0;i<  al.size();i++){

    de=(DataEntry)al.get(i);

    if(header.getStreamsize()==de.getStreamsize()){

      if(sn==de.getSn())

      break;

      else

      de=null;

    }

  }

  returnde;

  }

   /**

   *按序号开始向前或者是向后寻找最近的帧片段,日后可以增加请求重发功能,通过开一个通信连接.

  *@paramsnint

  *@returnDataEntry

  */

  privateDataEntryseachDeData(intsn){

   DataEntryde=null;

   intinitvalue,minvalue=10000;

   DataEntryback,fore=null;

   for(inti=0;i<  al.size();i++){

     de=(DataEntry)al.get(i);

     if(header.getStreamsize()==de.getStreamsize()){

       initvalue=Math.abs(de.getSn()-sn);

       if(de.getFragmentcounter()!

=de.getSn()&&initvalue<  minvalue){

      minvalue=initvalue;

      fore=de;

      }

    }

  }

  returnfore;

   }

  /**

  *除去最后一帧外,随机抽取一帧.

  *@returnDataEntry

  */

   privateDataEntryseachDeData(){

   DataEntryde=null;

   for(inti=0;i<  al.size();i++){

    de=(DataEntry)al.get(i);

    System.out.println("sky:

:

:

:

"+de.getFragmentcounter()+":

"+de.getSn()+

               ":

"+i);

    if(header.getStreamsize()==de.getStreamsize()){

      if(de.getFragmentcounter()!

=de.getSn()){

      break;

    }

    }

 }

  returnde;

  }

  /**

  *生成组装完的结果数据.因为用图像来做测试,所以令其返回图像.

  *@returnImage

  */

   publicjava.awt.ImageGereratedata(){

    ByteArrayInputStreambis;

    java.awt.image.BufferedImagebimage=null;

    try{

    byte[]b=fetchDataPackets_sn().toByteArray();

    //fetchDataPackets_old1()

    bis=newByteArrayInputStream;

    bimage=javax.imageio.ImageIO.read(bis);

  }

    catch(Exceptionex1){

    ex1.printStackTrace();

  }

    returnbimage;

 }

  publicstaticvoidmain(Stringargs[]){

  DataPacketdp=newDataPacket("e:

\\nature\\14.jpg");

  }

 }

  /**

  *数据实体,充当临时处理场所.

  *@authorAdministrator

  *

  */

  classDataEntry{

  byte[]bytes;

   intfragmentcounter,sn,actbytesize;

   longstreamsize;

   intminfragment;

  publicDataEntry(){

  }

   publicDataEntry(intsize){

   this.actbytesize=size;

  }

   publicDataEntry(byte[]b,inti){

   this.bytes=b;

   this.actbytesize=i;

  }

  publicbyte[]getByte(){

   returnthis.bytes;

   }

   publicvoidsetBytes(byte[]b){

   this.bytes=b;

  }

   publicvoidsetStreamsize(longsize){

   this.streamsize=size;

   }

   publiclonggetStreamsize(){

   returnthis.streamsize;

  }

   publicintgetMinfragment(){

   returnminfragment;

  }

   publicsynchronizedvoidsetSn(inti){

   this.sn=i;

  }

   publicsynchronizedintgetSn(){

   returnsn;

  }

   publicsynchronizedintgetFragmentcounter(){

   returnfragmentcounter;

  }

   publicsynchronizedvoidsetFragmentcounter(intc){

   this.fragmentcounter=c;

  }

   publicvoidsetActByteSize(intsize){

   actbytesize=size;

  }

   publicintgetActByteSize(){

   returnactbytesize;

   }

   publicStringtoString(){

   returnthis.streamsize+":

:

"+this.fragmentcounter+":

:

"+this.

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1