mikaelpatel / Cosa

An Object-Oriented Platform for Arduino/AVR
https://mikaelpatel.github.io/Cosa/
GNU Lesser General Public License v2.1
338 stars 76 forks source link

W5?00: Only first connection works #499

Closed jeditekunum closed 6 years ago

jeditekunum commented 6 years ago

This happens on W5500 but since the code is mostly shared with other W5x00 I imagine the problem exists there too.

The following code works. Comment out the end()/begin() in ::on_disconnect and it will only work for the first connection. Quit the first session and try again and the client says "Connection refused".

Tcp.txt (Tcp.ino)

mikaelpatel commented 6 years ago

Unfortunately I have not tested the W5500 or the latest changes to W5X00. They came in on a PR.

jeditekunum commented 6 years ago

That was my PR. It should not have affected this. I don't have any of the other models.

For the moment the most that I can say is that this probably never worked. A disconnect closes the socket in the device. This listen actually fails because its closed.

For the time being I don't have time to investigate this further. I'm confused by the design. In "normal" implementations one binds a socket, does a listen, waits/checks for event, and then accepts. Accept always returns another socket. I haven't yet figured out if the difference in design is Cosa or Wiznet.

dansut commented 6 years ago

@jeditekunum this rang a bell for me. If you look back to my initial work in this area #370 you will see I could never get the W5200 to work beyond the first connection - I never had any problems with the W5500 though.

Little chance of me finding time to help out right now but maybe this snippet of a clue might help find root cause of this.

jeditekunum commented 6 years ago

Just to clarify. The end/begin in the disconnect handling actually doesn't work. The client doesn't get a connection refused but nothing else works.

In looking at the Wiznet documents it seems that it functions differently than traditional implementations. Sockets are hardware channels and there are only 4-8 of them.

jeditekunum commented 6 years ago

I now have a workaround that seems to be fully functional. The example above works with:

void loop()
{
  if (server.run())
    {
      // Cannot connect again without this
      ASSERT(server.begin(ethernet.socket(Socket::TCP, Telnet::PORT)));
    }
}

If anyone with a W5100 or W5200 could test then hopefully we can have a common fix.

jeditekunum commented 6 years ago

Thanks