4

I am subscribing to a multicast UDP stream in MATLAB. This can't done done natively, so instead I am using a java.net.MulticastSocket object. Each UDP packet is tagged with some meta-data, in particular a sequence count. Every time my data source sends a UDP packet, that sequence count is incremented.

Here's my skeleton code:

s = java.net.MulticastSocket(50001);
s.setSoTimeout(15000);
s.setReuseAddress(1);
s.setReceiveBufferSize(32768);
s.joinGroup(java.net.InetAddress.getByName('239.255.0.4'));
p = java.net.DatagramPacket(zeros(1, 1600, 'int8'), 1600);

ii = 1;
d = cell(10000,1);

while ii < 10000
    s.receive(p);
    d{ii} = p.getData;
    d{ii} = d{ii}(1:p.getLength);

    ii = ii + 1;
end

Once I catch all the data, I can post-process it; that bit isn't important.

After catching 10,000 packets like this, I look at the sequence count and it turns out I'm missing packets. That's fair; this is UDP after all so there's no guarantee of receipt of traffic. However, what's really interesting is I'm only receiving every 256th packet:

sequenceCnt =
    ...
    56637
    56893
    57149
    57405
    57661
    57917
    58173
    58429
    58685
    58941
    59197
    59453
    ...

I have Wireshark running and watching the data stream coming in, and the packets are definitely incrementing. So my computer is seeing the multicast stream in its entirety (i.e., not dropping packets because UDP doesn't guarantee delivery), but this little MATLAB/Java code is unable to keep up with the stream.

Any idea what is going on? I have basically zero Java experience, so any help would be appreciated.

Dang Khoa
  • 5,693
  • 8
  • 51
  • 80
  • I can't quite make up your while loop; are the `d{ii} ...` lines simple assignments? – fge Mar 13 '14 at 22:02
  • Yes, `d` is a [cell array](http://www.mathworks.com/help/matlab/cell-arrays.html). All I'm doing is fetching the data, then `trimming` it based on the length. I use a cell array here instead of a matrix because there's no guarantee that the lengths of the data streams are the same size. (MATLAB only allows you to build matrices if the number of rows is the same.) – Dang Khoa Mar 13 '14 at 22:08
  • Can you post process the assignment to this cell array to only after you have received all the data? – fge Mar 13 '14 at 22:11
  • No, I can do it inside if desired. That's how my original code is. For purposes of this question I wanted to make sure my processing code wasn't the bottleneck for data being dropped, so I moved the postprocessing outside the loop – Dang Khoa Mar 13 '14 at 22:23
  • Ah, OK, so even with this code outside, you see the problem? Interesting... I take it increasing the buffer size does not help either? – fge Mar 13 '14 at 22:39
  • No it does not. I can try again next time I have access to that multicast stream (Monday). – Dang Khoa Mar 13 '14 at 23:14

1 Answers1

2

Even if your receiver misses some packets (being datagram) it is extraordinarily unlikely to miss exactly 255/256 consistently. Did or can you check the number of packets wireshark shows (filtered as necessary) for the time interval your receiver was running?

My guess is you're getting the seq values wrong because of endianness or alignment in parsing the packet contents, which you don't show. Make sure the receiver reads the same two(?) bytes the sender used for seq, and in the correct order -- wireshark should show the exact layout. If you use DataInputStream Java defines multibyte numbers as big-endian, and everything as byte-aligned; for other code I can't say.

Also, I assume that either the cell assignment or the 'trim' operation (always) copies the selected part of the byte array, like (perhaps using) Arrays.copyOf(T[],int). DatagramSocket and DatagramPacket by themselves re-use the same buffer, so if assign the getData() reference on each iteration, you'll have N pointers all to one buffer which contains only the data after the last receive.

dave_thompson_085
  • 34,712
  • 6
  • 50
  • 70
  • I'll take a look at the endianness this morning, but everything else in the packet is correctly formed. The fact that I'm dropping a multiple of 2 like this is what makes me think it's not actually a drop but it's somewhere else.. – Dang Khoa Mar 17 '14 at 15:15
  • endianness might be an issue it looks like. half my words are correct though. might be a problem with the spec I'm working to. – Dang Khoa Mar 17 '14 at 20:37
  • I feel pretty dumb for not looking at endianness more closely. I was typecasting data from `uint8` to `uint16`, and MATLAB uses the first element of a given vector to be typecast as the *least* significant byte (i.e., if I had word `0x12ab` then `d(1) == 0xab` and `d(2) == 0x12`). What's worse, some of my dummy data was a palindrome (`0x3030`, for instance) so half the time it looked correct. Thanks for getting me to look at this from a different angle. – Dang Khoa Mar 19 '14 at 02:40