Доброго времени!
Организую сервер на базе w5500 и библы Ethernet.
Все делаю, как по мануалу https://docs.arduino.cc/libraries/ethernet/#Server%20Class
void loop() {
// check for any new client connecting, and say hello (before any incoming data)
EthernetClient newClient = server.accept();
if (newClient) {
for (byte i = 0; i < 8; i++) {
if (!clients[i]) {
newClient.print("Hello, client number: ");
newClient.println(i);
// Once we "accept", the client is no longer tracked by EthernetServer
// so we must store it into our list of clients
clients[i] = newClient;
break;
}
}
}
// check for incoming data from all clients
for (byte i = 0; i < 8; i++) {
while (clients[i] && clients[i].available() > 0) {
// read incoming data from the client
Serial.write(clients[i].read());
}
}
// stop any clients which disconnect
for (byte i = 0; i < 8; i++) {
if (clients[i] && !clients[i].connected()) {
clients[i].stop();
}
}
}
Для моих задач клиент должен оставаться подключенным к серверу до собственного отключения, для отправки клиенту данных использую
if (clients[i]) {
if (clients[i].connected()) {
clients[i].write(buff, sizeof(buff));
clients[i].flush();
}
}
Все работает, но стал замечать, что иногда МК перегружается при отправке. Ресерч показал, что проблема в flush(), если клиент аварийно отключился (потерял коннект с сервером), то для сервера он все еще живой, то есть все проверки if (clients[i]), if (clients[i].connected()) проходят, а внутри flush() программа зависает в бесконечном цикле
void EthernetClient::flush()
{
while (_sockindex < MAX_SOCK_NUM) {
uint8_t stat = Ethernet.socketStatus(_sockindex);
if (stat != SnSR::ESTABLISHED && stat != SnSR::CLOSE_WAIT) return;
if (Ethernet.socketSendAvailable(_sockindex) >= W5100.SSIZE) return;
}
}
Вот думаю, что с этим сделать? Самое простое видится добавить выход из цикла по таймауту, с последующей принудительной остановкой клиента, но может есть какие еще мысли? Просто странно, что за столько времени никто это не правил.