Search code examples
javaarraysloopsreferencedatagram

When creating an array of DatagramPackets, each element becomes the same as the most recent element added


public DatagramPacket[] makePackets(byte[] data, InetAddress IP, int portNumber)    {
   // create packet buffer
   ByteBuffer buffer = ByteBuffer.allocate(packetSize);

   // calculate number of packets
   int dataSize = packetSize - 10;
   int totalPackets = data.length / dataSize;
   if(data.length % dataSize > 0)
       totalPackets++;

   System.out.println("Total Packets " + totalPackets);

   DatagramPacket[] pkts = new DatagramPacket[totalPackets];

   for(int seqNumber = 0; seqNumber < totalPackets; seqNumber++)
   {
       // insert metadata
       buffer.putChar(informUpdate);
       buffer.putInt(seqNumber);
       buffer.putInt(totalPackets);

       // adds data to the buffer
       if(seqNumber == totalPackets -1) // if last packet adjust length to avoid null pointer
           buffer.put(data, seqNumber * dataSize, data.length - seqNumber*dataSize);
       else
           buffer.put(data, seqNumber * dataSize, dataSize);

       // create packet
       byte[] sendData = buffer.array();
       // add packets to packet array and clear buffer
       pkts[seqNumber] = new DatagramPacket(sendData, sendData.length, IP, portNumber);
       System.out.println(new String(pkts[seqNumber].getData())); // <- Check if packets are being made correctly
       buffer.clear();
   }
   // this shows prints all elements in pkts which proves all data is the same
   for(int i = 0; i < pkts.length; i++)
       System.out.println(new String(pkts[i].getData()));
   return pkts;    }

Hopefully I've added my code in a readable format. Thanks ahead of time!


Solution

  • When you do this:

    byte[] sendData = buffer.array();
    

    You are retrieving the same byte array in each loop iteration. Each DatagramPacket you create is reusing that same byte array.

    The easiest solution is to clone the byte array, since every array in Java has a public clone() method which throws no exceptions:

    byte[] sendData = buffer.array().clone();