Open SamuelPittet opened 6 years ago
I too noticed that if the remote peer fails without closing the socket, socketSend() waits forever.
I'd hesitate to add an availableForWrite() in EthernetClient::write as proposed here though. A busy network or slow peer could easily cause the proposed code to return an error instead of just waiting a bit until room becomes available in the socket's TX buffer and going on as if nothing had happened. If the proposed change were made, the application would have to distinguish between real client failures and network delays.
This would be a good place to add a timeout to prevent the function from hanging up indefinitely. Using availableForWrite() in applications before client.write() calls will prevent hangups in the meantime.
Here's quick & dirty example of what I'm proposing:
// if freebuf is available, start.
**uint32_t start = millis(); // record time loop is entered** +rs 17Feb2019
do {
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
freesize = getSnTX_FSR(s);
status = W5100.readSnSR(s);
SPI.endTransaction();
if ((status != SnSR::ESTABLISHED) && (status != SnSR::CLOSE_WAIT)) {
ret = 0;
break;
}
**if (millis() - start > 1000) { // check for timeout +rs 17Feb2019 - find a way to use user-configurable _timeout
ret = 0;
return ret;
}**
yield();
} while (freesize < ret);
I had an occurence where Ethernet.socketSend() is hanging about 20s. After verification, this is due to Ethernet.socketSendAvailable not having enough space on the output buffer.
This is easily replicable by connecting to a websocket server and sending data regularly. Then, disconnect Ethernet cable and continue to send to websocket server. When the data to be sent have a greater size than the remainder of the 2048 bytes buffer of the W5100, Ethernet.socketSend() will hang for about 20s.
I think that simply using this new EthernetClient::write should do the trick :
Have a good day!