【问题标题】:Send file part by part with UDP使用 UDP 部分发送文件
【发布时间】:2015-02-20 14:22:40
【问题描述】:

我会在我的服务器端发送一个拆分为 N 个部分的 XML 文件。

每个文件在开始时都包含以下信息:fileNumber 和 totalPart

例如,如果我有 32 个部分: - 第一个文件在开始时包含:0(文件编号)和 32(总部分) - 第二个文件在开始时包含: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();
     }
}

如您所见,我的第一个想法是:在客户端,我创建一个包含布尔值 (False) 的 ArrayList partReceive,当我收到一个零件时,我将 ArrayList 的索引设置为“True”。但是在我如何处理之后?

【问题讨论】:

    标签: java android udp


    【解决方案1】:

    我想到的两种可能的方式:

    1. 使用 TCP。它会自动确保按顺序接收所有数据包。
    2. 也许您故意要使用 UDP。我不太了解您的 ArrayList partReceive 的含义。该循环将始终将所有元素设置为 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 秒内没有收到任何数据包,则认为传输已完成。然后检查丢失了哪些数据包。

    【讨论】:

    • 我应该使用 UDP 我没有选择,如何为每个数据包分配一个 ID?以及如何确定传输完成?我有一个while循环..我的partReceive ArrayList的意义是检查我是否收到了第二个数据包,例如,我检查partReceive.get(1),如果它返回false,我还没有收到第二个数据包,但是如果它返回 true,我已经收到了这个数据包...
    • 查看我修改后的答案。还有其他问题吗?
    • 你能给我一个为我的代码设置超时的例子吗?
    • 谢谢,但在我的情况下,我如何验证我是否在 x 秒内没有收到任何数据包?
    猜你喜欢
    • 1970-01-01
    • 2015-03-06
    • 2020-01-07
    • 1970-01-01
    • 2016-02-15
    • 1970-01-01
    • 2014-04-12
    • 2012-12-09
    • 2012-03-14
    相关资源
    最近更新 更多