Ethernet icon indicating copy to clipboard operation
Ethernet copied to clipboard

EthernetServer available() is confusing

Open agdl opened this issue 8 years ago • 11 comments

From @lestofante on March 15, 2013 10:29

Copied from original issue: arduino/Arduino#1320

EthernetServer.available() returns the first socket connected (or waiting for close) with data in RX buffer.

This is bad because:

  • User tends to think available() returns the NEXT connected socket (even if it has no data into RX).
  • If there are multiple clients connected continually writing data to Arduino (or writing it at right moment), there can be a situation where you will never be able to read the last EthernetClient.

We have found 3 solution:

  1. Add a flag into EthernetClient: when returned by available() this client will never be returned thanks to this flag. The client is returned even is RX buffer is empty.
    • Can break some code.
  2. Add an EthernetServer.available(int) where user can choose what Socket to use. This should be invisible to the user, as it can overflow the array or receive non-connected EthernetClient,
    • Advantage is that this is an overloaded method, so old code will work.
  3. Add a new method like EthernetServer.getNextClient() which will use the flag method as in solution (1).
    • No retro-compatibility problem.
    • An easy way to get all client connected.
    • A method to get maximum number of client connected should be provided, or the constant MAX_SOCK_NUM should be public, so user can create their own EthernetClient array

(the last is probably the best)

Additional Context

Related discussion (in Italian):

https://forum.arduino.cc/t/accettare-piu-connessioni-in-ingresso-su-server-ethernet/150498

agdl avatar Jul 12 '16 13:07 agdl

@cmaglie - I believe we need this in the 2.0 API. Protocols like FTP can't be implemented with the existing API. I'm leaning towards EthernetServer.connected(), like these:

http://forum.arduino.cc/index.php?topic=146795.0 http://forum.arduino.cc/index.php?topic=169165.msg1346247#msg1346247 https://github.com/gallegojm/Arduino-Ftp-Server/blob/master/FtpServer/FtpServer.cpp

Any thoughts on the API. Is EthernetServer.connected() ok with you?

PaulStoffregen avatar Jul 23 '18 10:07 PaulStoffregen

The additional API is OK, please just use accept() instead of connected().

The reason is that connected() looks more like a function to query the state of the socket like, say, availble(), instead accept represents better the action of accepting incoming connections and it's also used in API of other languages.

cmaglie avatar Jul 23 '18 14:07 cmaglie

Also the older available() API would became orthogonal to this one, in a sketch you would use available() or accept() but not both. Also this change should find his way up to the cores and the documentation.

cmaglie avatar Jul 23 '18 14:07 cmaglie

@cmaglie If we're calling this "accept", maybe the behavior should be changed to mark the client as accepted, so it won't be returned again? Currently it's implemented very much like available(), where it will be returned repeatedly.

PaulStoffregen avatar Jul 23 '18 15:07 PaulStoffregen

Let me make sure I understand how we're intending these functions to work?

Using server.available(), the library keeps a list of all the clients and returns whatever client has recently sent data. Multiple clients may be connected, but a "false" client is returned if none have sent any data. The intended usage model is simple code which repeatedly calls server.available() to get the next client data.

Using server.accept(), the user's sketch must keep track of which client(s) are connected. When a client connects, it is returned once regardless of whether it has sent any data. The sketch must keep track of the client, because server.accept() will not return the same client again.

Does that sound right?

PaulStoffregen avatar Jul 23 '18 15:07 PaulStoffregen

Using server.accept(), the user's sketch must keep track of which client(s) are connected. When a client connects, it is returned once regardless of whether it has sent any data. The sketch must keep track of the client, because server.accept() will not return the same client again.

Correct. I thought that this was the behaviour of the new connected() function, sorry for the misunderstanding.

cmaglie avatar Jul 23 '18 16:07 cmaglie

Sounds good. I'll change it to this.

PaulStoffregen avatar Jul 23 '18 16:07 PaulStoffregen

I rewrote the AdvancedChatServer example to use EthernetServer accept(). It's working very nicely. :)

PaulStoffregen avatar Jul 24 '18 13:07 PaulStoffregen

@cmaglie - Who should we get involved in this conversation to update the website with the new functions?

PaulStoffregen avatar Jul 27 '18 03:07 PaulStoffregen

/cc @SimonePDA

cmaglie avatar Sep 10 '18 15:09 cmaglie

I have already added the Ethernet new APIs using the massive work done by per1234 in https://github.com/arduino-libraries/Ethernet/issues/67.

You can see them online here: https://www.arduino.cc/en/Reference/Ethernet

Let me know if something needs fixes or further information.

SimonePDA avatar Sep 10 '18 15:09 SimonePDA