LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

multiple TCP callbacks generated by single Ethernet frame

  I'm sending small amounts of data between a CVI TCP client and server.  The client can ClientTCPWrite() to the server with, say, 20 bytes of data.  All of this is going in a single Ethernet frame across the network (I know this because I watched it with analyzer).  The strange thing is that the server gets a callback for the inbound frame, but it only has 4 bytes of data immediately available for a 1000 msec timeout.  The remaining 16 bytes of data come back as four additional 4-byte callbacks.  Basically, one ClientTCPWrite() results in five ServerTCPRead()s.
 
  How can that be efficient?  If the data arrives in one frame at the server, it should ideally generate one callback for that single frame, right?  If the data was so large that it arrived in several frames then I might be able to understand, but gee whiz!  And, no, my inbound buffer size is not 4 bytes.  What am I missing here?  How can I force the CVI TCP libraries to be more efficient?
 
Orlan
0 Kudos
Message 1 of 6
(3,906 Views)

OK, never mind.  Shortly afterwards I started noticing 'file not found' errors when I tried to use the Find UI Object functionality from the source window.  I think my computer was smoking something.  After a reboot the single frames are now being reported in single callbacks.  All is well.

Orlan

0 Kudos
Message 2 of 6
(3,897 Views)
The CVI TCP library does not guarantee a single callback invocation per frame. The library will invoke the callback function if there is ANY data to be read in the connection. I believe this is how the lower-leve Winsock events also work. So I think it is safer to design CVI applications without relying on any association between TCP callback invocations and ethernet frames. Consider the case where the user reads only part of the data in the frame (for whatever reason) - the callback will be invoked again because there is remaining data that needs to be read.
0 Kudos
Message 3 of 6
(3,881 Views)

Hi Mohan,

  That's a good point.  I already had that code written because there might be a full Ethernet frame that comes in (up to 1500 bytes for data) that would be larger than my 512 byte (actually 513 byte) buffer.  I also have to strtok() my inbound buffer because there could also be, in a bad case, multiple smaller variable-length delimited messages queued up by the time I get around to ServerTCPRead().  I guess if there are lots and lots of tiny messages it might become more efficient to just poll the buffer with ...Read() using an async timer or something, instead of handling all of those callbacks?  It would probably take a lot to hit that crossover point.  Maybe when you get to overwelmingly high traffic volume on gigabit ethernet?

Orlan

0 Kudos
Message 4 of 6
(3,877 Views)

Yes, the user can just poll for data by calling the CVI Read function at regular intervals. But there is no buffer exposed for polling. The lower level Windows sockets does not expose any buffer for reading and so the CVI TCP library also does not do this. So the user has to read the data from the connection into a user buffer and then do the search on the user's buffer.

0 Kudos
Message 5 of 6
(3,858 Views)

Cosmo,

You can find out more about the CVI TCP library from this document. There is a section in this doc that discusses the streaming nature of TCP, which might be of interest to you.

Bilal Durrani
NI
0 Kudos
Message 6 of 6
(3,833 Views)