Does TCPClient just suck in general?


#1

I’ve been tearing my hair out trying to discover why it’s so weird. Like, why does available() block for 100ms? Why when I read one byte at a time do I get all the data I’m trying to read, but if I read multiple bytes at a time into a buffer it behaves so annoyingly… like, available() says there are 150 bytes, and I do a read() for 64, but it only returns 38? Are other people successfully using TCPClient? I see a lot of trouble reports going back to 2013, but it’s not clear to me how much is still applicable. Should I just use Particle.function()s and give up on TCP? Thanks for any advice.


#2

A lot will depend on your device and system firmware version.

For Wi-Fi devices (Photon, P1), 0.6.3 is probably the best for TCP, followed by 0.8.0-rc.11. In 0.7.0, the WICED library that implements the Wi-Fi and TCP stack was upgraded, and it included a change in the IP stack that caused some unexpected changes in behavior. Much of this was straightened out in by the later 0.8.0-rc versions.

For cellular devices, you’re at the whim of the cellular modem module. My guess is that you are using a cellular device if available() is blocking, because it needs to query the modem. Performance there will depend on whether you use SYSTEM_THREAD(ENABLED) or not. I’d definitely recommend it if using TCPClient.

In any case, you’ll get much better performance if you always attempt to read a full 1024 bytes of data on read and never call available().


#3

Thanks for this. I’m using an Electron/e-series running 0.8.0-rc.10. Does it really take 100ms to talk to the modem? I will try refactoring the code to read bigger blocks.


#4

No, it won’t always take that long, but modem operations are generally synchronous and happen only on one thread (either the system thread or the application thread depending on SYSTEM_THREAD mode) and it’s possible that you can get blocked waiting for a shared resource.


#5

Oh yeah I forgot to mention that I’m running with SYSTEM_THREAD(ENABLED), so I was assuming that I wouldn’t block… that either there would be bytes I can pull from the buffer, or not.