Search code examples
javajava-iodatainputstreambytearrayoutputstreambytearrayinputstream

Order byte array by the DataInputStream int


I have audio packets with a sequence number at the start, which is 4 bytes.

ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeInt(sequenceNumber);

I receive the packets in a random order, which I then place into a buffer, so an array of arrays.

I was wondering what would be the best way to order the packets by the sequence number.

I retrieve the sequence number like:

 ByteArrayInputStream bos = new ByteArrayInputStream(udpPacketBytes);
 DataInputStream ds = new DataInputStream(bos);
 int receivedValue = ds.readInt();

Is there a way without removing the sequence number that I can order the entire byte array by said sequence number?


Solution

  • You can do

    byte[] bytes = new byte[ds.available()];
    ds.readFully(bytes);
    

    to get the remaining bytes.

    To ensure the packets are in the original order, you need to check the sequence number is 1 more than the previous ones. If not, you need to save the packets by sequence number and re-order them. The more challenging problem is when packet are dropped you need to ask for the again.

    You could use something like

    public class OrderManager {
        int nextSequence = 0;
        final SortedMap<Integer, byte[]> buffered = new TreeMap<>();
        final Consumer<byte[]> consumer;
    
        public OrderManager(Consumer<byte[]> consumer) {
            this.consumer = consumer;
        }
    
        public void accept(int num, byte[] bytes) {
            if (num == nextSequence) {
                consumer.accept(bytes);
                nextSequence++;
                while (buffered.firstKey() == nextSequence) {
                    consumer.accept(buffered.remove(buffered.firstKey()));
                    nextSequence++;
                }
            } else {
                buffered.put(num, bytes);
            }
        }
    }
    

    Since out of order packets are rare but lost packets are fairly common you could treat an out of order packet as if it had been lost and send a packet to the producer to sent it again.