Zombie Sockets with W5500/WIZ850io
Thanks to @drmartin for his suggestions in
this thread... I have some socket status code in a fork of Paul's Ethernet library
here, on a simple
TempServer application. I'm seeing some strange socket behavior. There should be one socket listening and another establishing a connection, then getting closed. That's what I see. For a while. This is a single-threaded application, so incoming connection requests can only get handled one at a time. Yet, what happens is that multiple sockets (of the four available, less the one listening, so only a "pool" or shall we say "puddle" of three) wind up in "established" status. Meaning they are not available for use when a new request needs a connection. You can see this in the
detailed logs which I'm tracking as a means to try to understand what's wrong and how to fix it.
In the forked Ethernet library (github link above) socket.cpp, EthernetClass::socketBegin, I have this code compiled by changing to an "#if 1" from "#if 0":
Code:
#if 1
Serial.printf("W5000socket step3\n");
// next, use any that are effectively closed
for (s=0; s < MAX_SOCK_NUM; s++) {
uint8_t stat = status[s];
// TODO: this also needs to check if no more data
if (stat == SnSR::CLOSE_WAIT) goto closemakesocket;
}
#endif
and in the logs you can see this step3 getting executed, sometimes many times, before there is actually a socket available. This raises a lot of questions.
For one: where and how do I check to see if there is data which needs to be flushed? EthernetClient has a non-implemented flush function:
Code:
void EthernetClient::flush()
{
// TODO: Wait for transmission to complete
}
There are a lot of missing pieces in the Ethernet library, going back years of rejected pull requests. For one thing, the provided examples I've tried fail to run for long, and don't even pass
the W3 validator. There are few helpful source code comments, documentation is incomplete and sometimes incorrect, and there's little to help you debug quiet failures. There's no good way for mere mortals to contribute to the official Arduino community and remedy these. What is needed is something like
@nox771's i2c_t3 library which makes up for deficiencies in Wire. I'm going to attempt to do that since I have no other choice. Is there some other Ethernet library improvement effort going on already? I know Paul has put a lot of work into the existing library to add W5500/WIZ850io support, among other things.
W5500 Ethernet Resources
PJRC
Ethernet library
There is the Arduino.cc library
here
Adafruit
Ethernet 2 (not backwards compatible to W5100) which I have
used with M0 Pro and WIZ W5500 shield. This Adafruit library is based on WIZnet code of Soohwan Kim which has not seen any change in 2+ years.
Arduino.org
Ethernet2 library which now seems to have the same
source repo as arduino.cc, specifically
Ethernet same as Arduino.cc above so maybe the .cc and .org are finally
merged back together?
WIZnet
W5500 Forum
WIZnet
W5500 page with links to documents and code
With the simple changes so far, TempServer has now run for 151998 seconds (42 hrs) and 148675 http requests and recovered multiple times from no available sockets. Previously it would hang after at most a few hours, sometimes a few minutes.
There's a lot I need to learn about how sockets are supposed to work. I do have the
Comer/Stevens canonical text which I'm working through.
I like @nox771's approach of a struct per I2C "wire" instance. I may try a similar approach of a struct per W5500 socket.
Why is the library still not using all 8 possible sockets in the W5500? W5200 also had 8. There must be some reason this has not been implemented yet. My application ultimately wants a UDP socket to NTP, plus a listener and connection for TCP, leaving just one spare. That's enough for now, especially if the Zombie Socket issue can get fixed. But if I want to add a Telnet connection too, then it's full, and anything else new would be out of luck.