From 28ca40bb391985cbc79d9127bcde9f70f88c2b30 Mon Sep 17 00:00:00 2001 From: Frank Sauerburger Date: Thu, 21 Jan 2016 18:58:37 +0100 Subject: [PATCH] Providing a more fair servicing of multiple tcp clients. I modified `EthernetServer::available()` such that it will not always pick the socket with the lowest number that has data available. Instead when the method returned the client at socket i, it will check socket (i+1) % MAX_SOCK_NUM first when then method is called the next time. The problem with the previous implementation is that if there is a client connected to a socket with a low number (e.g. the first one with number 0) and the peer constantly sends data. In that case `EthernetServer::available()` always returns that client. The clients, which are connected to a socket with a higher number (e.g. 1, 2, or 3), can only be returned when the ones with lower numbers have no data available. This problem is fixed with this commit. This commit also implements the changes suggested by @matthijskooijman. --- libraries/Ethernet/src/EthernetServer.cpp | 12 ++++++++---- libraries/Ethernet/src/EthernetServer.h | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/libraries/Ethernet/src/EthernetServer.cpp b/libraries/Ethernet/src/EthernetServer.cpp index cfa813eb7be..22b3f91769e 100644 --- a/libraries/Ethernet/src/EthernetServer.cpp +++ b/libraries/Ethernet/src/EthernetServer.cpp @@ -52,13 +52,17 @@ EthernetClient EthernetServer::available() { accept(); - for (int sock = 0; sock < MAX_SOCK_NUM; sock++) { - EthernetClient client(sock); - if (EthernetClass::_server_port[sock] == _port) { + for (int i = 0; i < MAX_SOCK_NUM; i++) { + // increment _lastReturnedSocket to avoid returning the same socket again + _lastReturnedSocket = (_lastReturnedSocket + 1) % MAX_SOCK_NUM; + + EthernetClient client(_lastReturnedSocket); + if (EthernetClass::_server_port[_lastReturnedSocket] == _port) { uint8_t s = client.status(); if (s == SnSR::ESTABLISHED || s == SnSR::CLOSE_WAIT) { if (client.available()) { - // XXX: don't always pick the lowest numbered socket. + // doesn't always pick the lowest numbered socket, because of + // _lastReturnedSocket + 1 at the beginning return client; } } diff --git a/libraries/Ethernet/src/EthernetServer.h b/libraries/Ethernet/src/EthernetServer.h index 86ccafe9690..3ee72b318bb 100644 --- a/libraries/Ethernet/src/EthernetServer.h +++ b/libraries/Ethernet/src/EthernetServer.h @@ -10,6 +10,7 @@ public Server { private: uint16_t _port; void accept(); + int _lastReturnedSocket = -1; public: EthernetServer(uint16_t); EthernetClient available();