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?
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.