writeFully causes program to freeze
glen-02 opened this issue · comments
Hi, currently i am facing the following scenario:
Device 1 and 2 is an arduino board connected to a radio (Doodle Labs 20RM-2450-2J-XM) via ethernet cable. My task is to send data from device 1 to device 2.
device 1 performs:
client1.writeFully(message, sizeof(message))
device 2 performs
client2 = server.available();
cleint.read(buffer, sizeof(buffer));
where server is an EthernetServer object. and client[num] is an EthernetClient object.
a connection between an cleint1 on device 1 is already established with an server from device 2. and i received messages in device 2. To simulate a connection break i unplugged device 2 from its power source. However as soon as this happens my code on device 1 freezes on the method writeFully. Is there any way to set a timeout on device 1 to tell that it should stop trying to execute writeFully after a certain amount of time and move on with the rest of the code? Thank you
I think the underlying problem is the fact that it takes a long time for a TCP connection to realize it’s closed. writeFully()
loops until data is done or the connection is closed.
Having a timeout isn’t necessarily a bad idea, but I’d like to explore some alternatives. First, could you tell me if the link is detected as being down on device 1 when you unplug device 2? You can do this in a straightforward way by using a listener with Ethernet.onLinkState()
. See the LinkWatcher example (and some of the others) for an example of how to use this function.
You could also do this by modifying or duplicating the writeFully()
code to stop if “closed or !Ethernet.linkState()”.
Here:
QNEthernet/src/QNEthernetClient.cpp
Line 370 in 3281059
Change to:
return !static_cast<bool>(*this) || !Ethernet.linkState();
Another suggestion is to just close connections when link-off is detected.
Thanks for the suggestions, however i am more interested in setting a timeout so that the program can continue even when a connection breaks (not necessarily because of unplugging). The reason is that because my program should prioritize writing data to an sd card ( implemented on another part of the code) rather than transmitting it. Therefore i would like to ask wether you have any timeout functions or another suggestions?
My first comment wasn't a suggestion, it was a question to have you try something to verify what I think is the root of the problem.
Here's a function that has a timeout:
size_t writeFully(EthernetClient &c, const uint8_t *buf, size_t size, uint32_t timeout) {
uint32_t startT = millis();
return util::writeFully(c, buf, size, [&c, startT, timeout]() {
return !static_cast<bool>(c) || (millis() - startT) >= timeout;
});
}
I'm going to add some comments about this to the README. Thanks for the question.