TCP bulk data without PSH flag on each packet

Hello, we have an application that acts as a server responding to client requests. Usually responses are short and easily fit within a single packet.

Now we are trying to introduce responses that have to span multiple packets. On a similar device, we can see that bulk TCP transfers like this only have the ACK flag set on the first X packets, and only the final packet has the PSH and ACK flags set. Our Windows clients have no trouble receiving this entire packet as a single response.

I can’t seem to find a setting in the TCP library for the Rabbit that mimics this behavior and can’t find the right terminology to figure out why. We can send bulk data, but every packet has a PSH,ACK, which confuses any Windows client application as it thinks that is the full response.

Is there something I’m missing in the Rabbit libraries that would do this?

Thanks!

1 Like

TCP is a stream protocol, so data isn’t guaranteed to arrive in the same sized chunks as how you sent it. You’ll need to introduce some additional context to your data stream to indicate the start/stop of a response.

It might be possible to change the behavior of _tcp_send() in tcp.lib to only set PSH if there isn’t any more data queued to send. If you use sock_fastwrite() for writing data, and have enough buffer space enabled, this might work. Change these lines:


   else {
      sendpktlen = senddatalen + sizeof( tcp_Header ) + sizeof( in_Header );
      if (senddatalen)
         outFlags |= tcp_FlagPUSH;
   }

to (just adding “& !more” to the if):


   else {
      sendpktlen = senddatalen + sizeof( tcp_Header ) + sizeof( in_Header );
      if (senddatalen & !more)
         outFlags |= tcp_FlagPUSH;
   }

Please let me know the results of your test, and I will consider making it an official change to the library.

Hi Tom

Thanks for that update! That’s actually exactly what I ended up doing after reviewing tcp.lib and how it worked. That change produced some packets that did not have the PSH flag when writing larger blocks of data (until the last packet). It still seemed to inevitably force the flag when the data length exceeded the buffer size (2k, confirmed by forcing a 4k buffer as well).

This worked pretty well, but my original assumption that it was the PSH flag which indicated the end of stream was incorrect anyway. The client application had special handling to treat it like a stream (as you mention) with a known terminator.

Seems to me that was the intent of that “more” calculation, though, cus I couldn’t find anywhere else it was used.

  • James