UDP fread not returning entire datagram

I have an application where I am using UDP to get data from another application. I have my UDP object in DatagramTerminateMode, and I am calling fread in my callback.
The application was working just fine until today, and I am not exactly sure what I changed. Some calls to fread are only returning 256 bytes instead of roughly 8000 bytes. If I add a command to my callback and leave off the semicolon it seems to make everything work again.
This would suggest that fread is being called before data is ready, but I am in DatagramTerminateMode so there should always be a datagram available when the callback is executed.
You may also be thinking... "are you sure that datagram isn't actually 256 bytes?" Well I am rather certain that is it not... When I debug the other application it appear to never be sending a datagram less than 8000 bytes.

11 Comments

Are you using Gigabit Ethernet with Jumbo Packets enabled? If so is it possible that something in the network stopped supporting those?
Only Gigabit (and higher) Ethernet with Jumbo Packets support 8000+ byte payloads; for anything else, the packets would have to be fragmented. Relying on reliable delivery of multiple fragments of an unreliable datagram protocol has always seemed like an oxymoron to me.
Currently I am testing with both applications on the same machine. The machine does have gigabit, and I can ping localhost with 8192 byte packets.
That being said, when I drop the packet size down to something like 256 bytes I still have this problem. When I query 'event.Data.DatagramLength' within my callback it will return the correct value (256 byte), but fread will only read some portion of that. Note that fread will return a message like "The specified amount of data was not returned within the timeout period". The timeout period is 10 seconds, which I am not hitting. Plus I am calling fread from within the callback so an entire datagram should already be available.
In the final application there will be a local network dedciated to this data and this data alone. There will be multiple clients, so UDP broadcasts are making that easier. Additionally clients are ok with handling a small amount of data loss.
Experiment with passing a size to fread:
fread(udpobject, event.Data.DatagramLength, '*uint8')
In theory the size should be ignored when the datagram terminate mode is on, but let's try it just in case.
Jay
Jay on 17 Apr 2013
Edited: Jay on 17 Apr 2013
In my install (2010a) the UDP version of fread does not appear to support the '*' notation for maintining the source data type. The data is always returned as a double.
Changing the command to:
[data, count, MSG] = fread(udpobject, event.Data.DatagramLength);
produces the same results. Count will not always be equal to event.Data.DatagramLength.
Try 'uint8' instead of '*uint8'.
[data, count, MSG] = fread(udpobject, event.Data.DatagramLength, 'uint8');
will run, but the problem remains.
What count is being returned now? And what is DatagramLength currently?
Jay
Jay on 17 Apr 2013
Edited: Jay on 17 Apr 2013
I am currently trying with two differen packet sizes:
event.Data.DatagramLength = 249, count = 49
or
event.Data.DatagramLength = 505, count = 391
To aid in debuging, I have reduced the callback to simply be the fread command, and then a comparison of count to datagramlength.
Have you tossed on a network sniffer such as wireshark, just to verify that the packets are getting there correctly?
Have you tried sending a variety of packet contents, and checking whether there is any particular character that is causing the problems? Key characters I would check would be char(0), and CR and LF and char(26)
Jay
Jay on 19 Apr 2013
Edited: Jay on 19 Apr 2013
I have modified the data portion of the UDP packets to simply be:
  • int32 Index
  • lots of zeros
  • 0xAA
I am using this index to line up the erronous packets in matlab with the packets in wireshark.
I run my matlab application with a breakpoint checking whether the entire datagram was read. I break in the case that there is a partially read datagram. I then read out the packet index from matlab and find that packet in wireshark.
Wireshark shows the packet correctly: index, lots of zeros, 0xAA. 505 bytes of data total.
Matlab reports that there are 505 data bytes, but only read 391 bytes. The bytes that it read are correct, it just ends before it gets to the 0xAA.
As a precaution I have set udpobject.Terminator = '';
I think you should take this to tech support.

Sign in to comment.

Answers (0)

Categories

Asked:

Jay
on 15 Apr 2013

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!