0

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?

Aditya W
  • 652
  • 8
  • 20
  • I assume you mean "entire byte array **but** said sequence number" – Peter Lawrey Feb 23 '16 at 13:59
  • So i'm trying to order an array of byte arrays, the byte arrays contain the audio and the sequence number, i want to order by the sequence number then i can play the audio in the correct order –  Feb 23 '16 at 14:02

1 Answers1

0

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.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 1
    how does this order? –  Feb 23 '16 at 14:00
  • @user3667111 What do you mean? – Peter Lawrey Feb 23 '16 at 14:02
  • So i'm trying to order an array of byte arrays, the byte arrays contain the audio and the sequence number, i want to order by the sequence number then i can play the audio in the correct order –  Feb 23 '16 at 14:05
  • Writing a byte[] and then reading it again won't change it's order. – Peter Lawrey Feb 23 '16 at 14:06
  • oh sorry I haven't explained myself properly, I have purposely placed the byte[] into a buffer, then disordered them. Because I'm testing on a setup network which ensues packetloss. So I'm making sure I don't lose many packets in a row, so disorder them on client then reorder them on server –  Feb 23 '16 at 14:12
  • @user3667111 in that case you need to write a component which will store and replay any packets which we out of order. Most of the time they will be in order. – Peter Lawrey Feb 23 '16 at 15:29
  • That's the question, how do I make this component, or what is the best way to go about it –  Feb 23 '16 at 15:32
  • Thank you for the answer, what about when packets are lost? this would just crash right? –  Feb 23 '16 at 16:00
  • @user3667111 this would just stop until the missing packet turned up. (or not) – Peter Lawrey Feb 23 '16 at 16:03
  • Yeah thought so, how do you generally prepare for such a situation? –  Feb 23 '16 at 16:03
  • @user3667111 reliable UDP is a complex subject. You could read https://github.com/real-logic/Aeron to see what a full implementation looks like – Peter Lawrey Feb 23 '16 at 16:04
  • @user3667111 re-transmits, ACKs and NACKs and preventing NACK storms is a more complex subject. Re-ordering entries is trivial by comparison with is why I wrote it in 5 mins. Handling NACKs could takes months to get right by comparison. – Peter Lawrey Feb 23 '16 at 16:05
  • Could you maybe talk me through how your code works? is it recursive? Just a little confused –  Feb 23 '16 at 16:09