重發(fā)消息有兩個原因:①接收方未收到,此時重發(fā)是應(yīng)該的铅辞。②接收方收到消息但是發(fā)回的應(yīng)答包丟失了谋国,此時重發(fā)消息則重復(fù)了葵礼,所以在接收方還得添加一個機制:若收到的消息與以前發(fā)過的消息重復(fù)号阿,則再次發(fā)送應(yīng)答包。在這些機制下鸳粉,能夠初步的保證UDP傳輸?shù)耐暾匀咏А榱薝DP包不在IP層上被分片,所以設(shè)計UDP包每個不得大于以太網(wǎng)的MTU.采用相互握手重發(fā)
直接看代碼
public voidrun() {
try{
String local_path = Environment.getExternalStorageDirectory().getPath() +"/gateway_update_file/"+ file_name;
File local_file =new File(local_path);
int size =new Long(local_file.length()).intValue();//文件總的大小
System.out.println("文件總的大小"+" = "+ size);
if(size ==0) {
//當前文件為0届谈,重新獲取文件
//........
return;
}
//SEND_SIZE此變量為每包發(fā)送的大锌菀埂(跟接收返回的發(fā)送包大小)
PACKETS= (size /SEND_SIZE) +1;//跟接收方定義的接收總的包數(shù)(即發(fā)送多少包)
InetAddress inetAddress = InetAddress.getByName(GW_IP_ADDRESS);
if(socket==null) {
socket=newDatagramSocket(null);
socket.setReuseAddress(true);
socket.bind(newInetSocketAddress(Constants.UDP_PORT));
socket.setSoTimeout(3000);
}
inti;
int count =1;
FileInputStream fin =new FileInputStream(local_file);
byte[] bytes =new byte[SEND_SIZE];
while((i = fin.read(bytes,0,SEND_SIZE)) != -1) {//循環(huán)讀取文件
byte[] send_byte = GatewayCmdData.FileDataToGatewayCmd(PACKETS, count, bytes);//此byte數(shù)組為與接收方定義的數(shù)據(jù)結(jié)構(gòu)體
DatagramPacket data =newDatagramPacket(send_byte, send_byte.length, inetAddress, Constants.UDP_PORT);
socket.send(data);
Log.i(TAG+"發(fā)送的byte = ", Arrays.toString(bytes));
while(true) {
byte[] rec_byte =new byte[128];
DatagramPacket getack =newDatagramPacket(rec_byte, rec_byte.length);
socket.receive(getack);
if((int) MessageType.A.SEND_UPDATE_FILE_TO_GATEWAY.value() == rec_byte[11]) {過濾掉無用數(shù)據(jù)
ParseGatewayData.ParseUpdateCountData startUpdateData = new ParseGatewayData.ParseUpdateCountData();
startUpdateData.parseBytes(rec_byte);解析接收到的數(shù)據(jù)包含發(fā)送的數(shù)據(jù)包次數(shù)(即第幾包)
if(count == startUpdateData.packet_count) {//如果返回的數(shù)據(jù)包次數(shù)與發(fā)送包次數(shù)一致艰山,則發(fā)送下一包
if(startUpdateData.packet_count==PACKETS) {//最后確認包(即已經(jīng)完成相關(guān)操作)
String crc32 = GatewayInfo.getInstance().getGatewayUpdateCRC32(context);
byte[] bt = GatewayCmdData.FinallyUpdateCmd(crc32);
DatagramPacket packet =newDatagramPacket(bt, bt.length, inetAddress, Constants.UDP_PORT);
socket.send(packet);
Log.i(TAG+" = ", TransformUtils.bytesToHexString(bt));
System.out.println("發(fā)送最后一包= "+ TransformUtils.bytesToHexString(bt));
booleanisRun =true;
while(isRun){
socket.receive(getack);
if(rec_byte[32] ==0){
System.out.println("更新成功");
fin.close();
if(socket!=null){
socket.close();
最后關(guān)閉socket湖雹、文件流
}
isRun =false;
DataSources.getInstance().GatewayUpdateResult(0);
}else{
System.out.println("更新失敗");
DataSources.getInstance().GatewayUpdateResult(1);
}
Log.i(TAG,"最后一包返回值= "+ Arrays.toString(rec_byte));
}
}
System.out.println("發(fā)送下一包= "+ count);
count++;
break;
}
}else{
Thread.sleep(1000);
System.out.println("未接收到返回重新發(fā)送= "+ count);
socket.send(data);
}
}
}
}catch(Exception e) {
e.printStackTrace();
}finally{
System.out.println("finally = "+"UpdateHelper");
}
}