我会在服务器端发送一个分成N个部分的XML文件。
每个文件在开始时都包含以下信息:fileNumber和totalPart
例如,如果我有32个部分: - 第一个文件包含start:0(文件编号)和32(总部分) - 第二个文件包含start:1(文件编号)和32(总部分)...
使用for循环,我可以将所有部分同时发送给我的客户端。 但我的客户无法收到所有零件,我丢失了一些零件.. 我如何处理请求丢失的部分?
这是我的服务器端代码:
for (int i = 0; i < nbPart + 1; i++) {
File f = null;
BufferedReader br = null;
String content = "";
byte[] sendBuffer = null;
try {
f = new File("xml/file.part" + i);
br = new BufferedReader(new FileReader(f));
StringBuilder sbuilder = new StringBuilder();
String line = br.readLine();
while (line != null) {
sbuilder.append(line);
line = br.readLine();
if (line != null) {
sbuilder.append("\n");
}
}
content = i + ";" + nbPart + "#tag#" + sbuilder.toString();
int total = new Long(f.length()).intValue();
sendBuffer = new byte[total];
sendBuffer = content.getBytes();
DatagramSocket sendSocket = new DatagramSocket();
DatagramPacket sendPacket = new DatagramPacket(sendBuffer, sendBuffer.length, source, PORT_SEND);
sendSocket.send(sendPacket);
sendSocket.close();
Thread.sleep(timeToSend);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (br != null)
br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
这是我的客户端代码:
while (run) {
DatagramSocket receiveSocket = null;
DatagramPacket receivePacket = null;
data = "";
byte[] receiveBuffer = new byte[9999];
Arrays.fill(receiveBuffer, (byte) 0);
try {
receiveSocket = new DatagramSocket(PORT_RECEIVE);
receivePacket = new DatagramPacket(receiveBuffer,receiveBuffer.length);
receiveSocket.receive(receivePacket);
receiveSocket.close();
data = new String(receiveBuffer, receivePacket.getOffset(), receivePacket.getLength());
String datas[] = data.split("#tag#");
String dataParts[] = datas[0].split(";");
int numPart = Integer.parseInt(dataParts[0]);
totalPart = Integer.parseInt(dataParts[1]);
if(partReceive.isEmpty()){
for(int i=0;i<totalPart+1;i++){
partReceive.add(Boolean.FALSE);
}
}
File part = new File(filePath+"/file.part"+numPart);
if(part.exists()) part.delete();
writeToFile(part, datas[1]);
partReceive.set(numPart, Boolean.TRUE);
Log.wtf("Part"+numPart, partReceive.get(numPart).toString());
} catch (Exception e) {
e.printStackTrace();
}
}
正如你所看到的,我的第一个想法是:在客户端,我创建一个包含boolean(False)的ArrayList partReceive,当我收到一个部分时,我将ArrayList的索引设置为&#34; True&#34 ;。但在我如何处理之后?
答案 0 :(得分:0)
我想到了两种可能的方式:
partReceive
的意义。循环将alawys将所有元素设置为false,因为totalPart
在整个传输过程中是恒定的。在您的示例中,它将始终为32.我宁愿为每个数据包分配ID
。 ID是唯一编号。例如,您可以使用numPart
。收到数据包时,将其ID存储在列表中。整个传输完成后,检查仍然缺少哪些ID。最简单的方法是request each missing packet
。像这样的东西
ArrayList<Integer> receivedParts = new ArrayList<Integer>();
// save id of received packet
receivedParts.add(numPart);
// ...
// after transmission has finished
// Keep in mind that packets do not necessarily need to arrive in the same order like you've sent them when using UDP.
ArrayList<Integer> missingIDs = getMissingIDs(receivedParts);
for(Integer currentID : missingIDs) {
// request missing packets
requestMissingPacket(currentID);
}
有多种方法可以检查传输是否已完成:
receiveParts
列表的大小。timeout
。例如,如果您在x seonds期间没有收到任何数据包,请考虑完成传输。然后检查丢失的数据包。