Java数据报之失序和丢包Word下载.docx
《Java数据报之失序和丢包Word下载.docx》由会员分享,可在线阅读,更多相关《Java数据报之失序和丢包Word下载.docx(11页珍藏版)》请在冰豆网上搜索。
}
*在发送数据报时使用,它调用报文分割操作.
*@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){
//is=url.openStream();
URLConnectionconn=url.openConnection();
is=conn.getInputStream();
inttotal=conn.getContentLength();
header.CalcHeaderInfo(total);
//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++){
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);
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);
}
*为发送构造分组,没有考虑报头格式,也没有为分组编序号.
privatevoidmadeBody1(){
if(header.isWTailFragment(i))
is.read(body.getBody(),i*body.BODY_BUFFER_SIZE,
header.getMinfragment());
else
body.BODY_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;
*判断是否只有一个段.
publicbooleanisZero(){
returnthis.header.getSn()==0?
*该函数执行报文组装,不考虑丢失的报文.
privateByteArrayOutputStreamfetchDataPackets(){
ByteArrayOutputStreambos=newByteArrayOutputStream();
byte[]buffer=null;
DataEntryde;
for(inti=0;
al.size();
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){
returnbos;
*该函数执行报文组装,对于丢失的报文,写入空报文.
*@returnByteArrayOutputStream
*/
privateByteArrayOutputStreamfetchDataPackets_sn(){
ByteArrayOutputStreambos=newByteArrayOutputStream();
byte[]buffer;
DataEntryde;
for(inti=0;
header.getFragmentcounter();
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());
}
*对缓冲的数据包进行排序处理,即按顺序提取同一帧的数据,如果没有找到该序号的帧,则返回空值.
*@paramsnint要找的帧序号.
*@returnDataEntry
privateDataEntrygetSnData(intsn){
DataEntryde=null;
de=(DataEntry)al.get(i);
if(sn==de.getSn())
break;
else
de=null;
returnde;
*按序号开始向前或者是向后寻找最近的帧片段,日后可以增加请求重发功能,通过开一个通信连接.
*@paramsnint
*@returnDataEntry
privateDataEntryseachDeData(intsn){
DataEntryde=null;
intinitvalue,minvalue=10000;
DataEntryback,fore=null;
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;
*除去最后一帧外,随机抽取一帧.
privateDataEntryseachDeData(){
DataEntryde=null;
System.out.println("
sky:
+de.getFragmentcounter()+"
+de.getSn()+
if(de.getFragmentcounter()!
=de.getSn()){
*生成组装完的结果数据.因为用图像来做测试,所以令其返回图像.
*@returnImage
publicjava.awt.ImageGereratedata(){
ByteArrayInputStreambis;
java.awt.image.BufferedImagebimage=null;
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){
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.