Go Down

Topic: When writing a server, how do I distinguish between different clients? (Read 173 times) previous topic - next topic

ppelleti

I'm writing a server which more than one client might connect to at once.  When using the accept() method of EthernetServer, this seems fairly straightforward.  You get each client once, when it connects to the server, and then you keep track of the clients and interact with them separately.  So, you know which client a message came from, because you know which Client object you read it from.

Unfortunately the Ethernet library seems to be the only network library that supports accept().  In other libraries, such as WiFi or ESP8266WiFi, there is no accept() method on the Server.  Only the available() method is supported.

When using available(), a Client is returned when there is data ready to be read from it.  This mostly seems straightforward, except for one problem: how can I tell which client is which, so that I can associate it with state that I'm keeping about each connection?  The WiFiClient class doesn't seem to have an method that returns some sort of "identity" (e. g. a unique number), so I don't know how to identify if the Client returned by available() is one I've seen before.

Any idea how I would do this?  Thanks!

noiasca

how to react on postings:
- post helped: provide your final sketch, say thank you & give karma.
- post not understood: Ask as long as you understand the post
- post is off topic (or you think it is): Stay to your topic. Ask again.
- else: Ask again.

ppelleti

Sorry, I don't understand the answer.  Or rather, it seems like a re-statement of the question: how do I get a session ID for a Client?

Juraj

in ESP wifi libraries available() does what accept() in Ethernet.
but in ESP the connection is closed if all WiFiClient objects pointing to it are destroyed (out of scope).
(In Ethernet and other Arduino libraries the server.available() call will return the first client with data available() as documented. it can return a client object for the same connection again)

so if you modify the AdvancedChatServer example of Ethernet to ESP WiFi and use available() instated of accept() it will work the same way.


ppelleti

in ESP wifi libraries available() does what accept() in Ethernet.
Thanks!  Is that documented anywhere?  The page for the ESP8266 Server class just links to the available() method for the Arduino WiFi library.

Juraj

Thanks!  Is that documented anywhere?  The page for the ESP8266 Server class just links to the available() method for the Arduino WiFi library.

I think the esp8266 arduino team is not aware of this. But they can't change it now. Or maybe for version 3.00 I try to convince them to change it. There will be breaking changes and this one doesn't make a big difference in usual uses.

noiasca

Sorry, I don't understand the answer.  Or rather, it seems like a re-statement of the question: how do I get a session ID for a Client?
I tried to point you to session cookies. Generate the ID on your server and add it in the first answer in the HTTP header (set cookie).

https://en.wikipedia.org/wiki/HTTP_cookie
how to react on postings:
- post helped: provide your final sketch, say thank you & give karma.
- post not understood: Ask as long as you understand the post
- post is off topic (or you think it is): Stay to your topic. Ask again.
- else: Ask again.

ppelleti

I tried to point you to session cookies. Generate the ID on your server and add it in the first answer in the HTTP header (set cookie).

https://en.wikipedia.org/wiki/HTTP_cookie
What I'm doing has nothing to do with HTTP.  I'm writing a 9P server, but really that shouldn't matter.  This is not a protocol issue; this is a much more fundamental API issue.

My interpretation of the documentation for available() is that it just gives you data from all your clients jumbled up, and there is no way to tell them apart.  What I'm trying to find out is whether it's really as broken as it seems, or is there some way to work around this apparent limitation that I'm not seeing?

Juraj

What I'm doing has nothing to do with HTTP.  I'm writing a 9P server, but really that shouldn't matter.  This is not a protocol issue; this is a much more fundamental API issue.

My interpretation of the documentation for available() is that it just gives you data from all your clients jumbled up, and there is no way to tell them apart.  What I'm trying to find out is whether it's really as broken as it seems, or is there some way to work around this apparent limitation that I'm not seeing?
I hope I explained it. I started a chat with esp8266 core developers:

Quote
let's chat about WiFiServer Arduino API compatibility. The server.available() should return first client with data available. https://www.arduino.cc/en/Reference/WiFiServerAvailable (esp8266 doc points there). ESP8266WiFi library now does what EthernetServer.accept() method does https://www.arduino.cc/en/Reference/EthernetServerAccept. Could it be changed for 3.0? Rename available() to accept() and a new server.available() implemented to store references to all clients and then return the first one with data available?

ppelleti

I hope I explained it. I started a chat with esp8266 core developers:
Yes, thanks, I understood what you said.  I was replying to the other poster.

Although I'm glad that Ethernet and ESP8266 can do what I want, there are still a bunch of other WiFi libraries out there, such as WiFi, WiFi101, and WiFiNINA.  Ideally, I'd like my code to be as portable as possible.  But it sounds like I'll have to stick to Ethernet and ESP8266, because it seems that it isn't possible to write a multi-client server with the other libraries.

Juraj

Yes, thanks, I understood what you said.  I was replying to the other poster.

Although I'm glad that Ethernet and ESP8266 can do what I want, there are still a bunch of other WiFi libraries out there, such as WiFi, WiFi101, and WiFiNINA.  Ideally, I'd like my code to be as portable as possible.  But it sounds like I'll have to stick to Ethernet and ESP8266, because it seems that it isn't possible to write a multi-client server with the other libraries.

UIPEthernet and my EthernetENC for enc28j60 have accept()
my WiFiEspAT library has accept()

in my 3 and 1/2 year on Ardiono forum and Arduino SE there was nobody with the old WiFi shield
though WiFi101 and WiFiNINA are used by many.

ppelleti

UIPEthernet and my EthernetENC for enc28j60 have accept()
my WiFiEspAT library has accept()
Thanks, good to know!  That is very helpful.

Go Up