TCP client receive() call not honoring timeout

I’m trying to invoke receive() on a TCP client to flush its receive buffer. However, it is just blocking indefinitely even though I’m providing a timeout. Here is a code snippet:

        // query power status
        debugLog("flushing socket...");
        socket.receive({ timeout: 100 });         // to flush out anything in receive queue (but don't block if it's already empty)
        debugLog("socket flushed, sending command...");
        socket.send("op status ?\r");
        debugLog("getting response...");
        response = socket.receive({ timeout: 500 });
        debugLog("parsing response...");

After the console log shows “flushing socket…” it just hangs and the timeout never seems to expire? Thoughts on what I may be doing wrong? In this particular instance, I know the buffer is actually empty, but that shouldn’t matter, should it? I’m invoking this in onConnect() after I invoke connect().

You need to wrap that “receive” call in a try-catch. When it times out, an exception is thrown. That will abort the function if you don’t catch the error.

try {
  socket.receive({ timeout: 100 });
}
catch(err) {
  // Handle error
}

I’m still experimenting with this, but the try-catch didn’t resolve the issue I’m seeing when there is nothing in the receive buffer–the receive() call appears to block forever, regardless of the timeout and no exception is thrown. Is there a lower bound on timeout value? I played around with 1 and 100 and that didn’t seem to make a difference, but I’ve run out of ideas.

I’ll have to retest that. It is possible it’s no longer behaving as expected. I’ll get back to you.

The receive timeouts aren’t working for me either. I only tested the simulator. Didn’t try in the actual apps. There isn’t going to be much I can do to fix this because those are set on the system class. The only other way I can abort the receive call is by doing a close which I do not want to do in this case.

The next release is going to include a new available property on the TCPClient. This will return the number of bytes that are currently in the receive buffer. So instead of using a timeout you can do something like this to clear the buffer prior to sending your command.

if(socket.available > 0)
{
   socket.receive();
}

Hi Bill, glad you were able to reproduce the problem. I likewise only tested in the simulator, but I don’t think that matters–even if it worked in the apps, it’s very difficult to develop/test plugins and it also causes “Synchronize Devices” to hang as well (so it would probably hang the importing the plugin, although I didn’t specifically test that). The available property should do the trick, though, thanks!