2

Trying to setup a server on Arduino to support multiple clients, I am able to support one but I don't want to flush that client to make another connection.

#include <ESP8266WiFi.h>
const char* ssid = "your-ssid";
const char* password = "your-password";
// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);

void setup() {
  Serial.begin(115200);
  delay(10);

  // prepare GPIO2
  pinMode(2, OUTPUT);
  digitalWrite(2, 0);

  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.println(WiFi.localIP());
}

void loop() {
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  // Wait until the client sends some data
  Serial.println("new client");
  while(!client.available()){
    delay(1);
  }

  // Read the first line of the request
  String req = client.readStringUntil('\r');
  Serial.println(req);
  client.flush();

  // Match the request
  int val;
  if (req.indexOf("/gpio/0") != -1)
    val = 0;
  else if (req.indexOf("/gpio/1") != -1)
    val = 1;
  else {
    Serial.println("invalid request");
    client.stop();
    return;
  }

  // Set GPIO2 according to the request
  digitalWrite(2, val);

  client.flush();

  // Prepare the response
  String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now ";
  s += (val)?"high":"low";
  s += "</html>\n";

  // Send the response to the client
  client.print(s);
  delay(1);
  Serial.println("Client disonnected");

  // The client will actually be disconnected 
  // when the function returns and 'client' object is detroyed
}

Using this code, the server handles only one client at a time, but I need to connect multiple clents simultaneously.

  • Please post the code you're using (a minimal complete verifiable example stackoverflow.com/help/mcve) and perhaps someone will help you. – Mark Smith Nov 15 '16 at 20:58
  • Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. – sa_leinad Nov 25 '16 at 4:31
4

You need to keep track of multiple WiFiClients - declare an array of them, for example, and each time server.available() gives you a new one, store it in the array.

Then you need to make sure your code doesn't stick waiting for data from each item. You could service each WifiClient in turn: if it has data waiting (client[i].available() is true), read the data (client[i].read()) and store it. When you get a \r from a client, you know you have a whole line, and you can process it.

Here's a nearly-complete (but untested) example so you can see what I'm talking about. Naturally it's not the only way to do it.

#include <ESP8266WiFi.h>
const char* ssid = "your-ssid";
const char* password = "your-password";
#define MAX_CLIENTS 10
#define MAX_LINE_LENGTH 50
// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);
WiFiClient *clients[MAX_CLIENTS] = { NULL };
char inputs[MAX_CLIENTS][MAX_LINE_LENGTH] = { 0 };

void setup() {
  Serial.begin(115200);
  delay(10);

  // prepare GPIO2
  pinMode(2, OUTPUT);
  digitalWrite(2, 0);

  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.println(WiFi.localIP());
}

void loop() {
  // Check if a new client has connected
  WiFiClient newClient = server.available();
  if (client) {
    Serial.println("new client");
    // Find the first unused space
    for (int i=0 ; i<MAX_CLIENTS ; ++i) {
        if (NULL == clients[i]) {
            clients[i] = new WiFiClient(newClient);
            break;
        }
     }
  }

  // Check whether each client has some data
  for (int i=0 ; i<MAX_CLIENTS ; ++i) {
    // If the client is in use, and has some data...
    if (NULL != clients[i] && clients[i]->available() ) {
      // Read the data 
      char newChar = clients[i]->read();

      // If we have the end of a string
      // (Using the test your code uses)
      if ('\r' == newChar) {
        // Blah blah, do whatever you want with inputs[i]

        // Empty the string for next time
        inputs[i][0] = NULL;

        // The flush that you had in your code - I'm not sure
        // why you want this, but here it is
        clients[i]->flush();

        // If you want to disconnect the client here, then do this:
        clients[i]->stop();
        delete clients[i];
        clients[i] = NULL;

      } else {
        // Add it to the string
        strcat(inputs[i], newChar);
        // IMPORTANT: Nothing stops this from overrunning the string and
        //            trashing your memory. You SHOULD guard against this.
        //            But I'm not going to do all your work for you :-)
      }
    }
  }

}
  • Should i create multiple server ir multiple clients – user28203 Nov 15 '16 at 21:50
  • No - you create one WiFiServer and it will give you a new WiFiClient for each client which connects. – Mark Smith Nov 15 '16 at 21:51
  • I have created an array of clients, how to use server.available with that – user28203 Nov 15 '16 at 21:52
  • Do you know how to put items into an array in general? – Mark Smith Nov 15 '16 at 21:58
  • Create_client (){ – user28203 Nov 15 '16 at 21:59
0

Here , I have used array of WiFiClient . The reason is array pointer will hold previous plus latest WiFiClients (emoteIP and remotePort ) and user will be able to choose which WIFiClient to be used for communication.

We can store IPAddress , Port as well as whole WiFiClient object in an array

 //===========================================
       WebServer  Wserver(80);

       WiFiClient Wclient;



       WiFiClient *Wificlients[10] = { NULL };

       int  Clientindex=-1;


       Wclient = Wserver.client(); // or  server.avilable() if WiFiServer

       Wificlients[Clientindex++]=new WiFiClient(Wclient);

       int   cntloggedinclient=0;
       int kk=0;

       while(Wificlients[kk] != NULL)
           {
               cntloggedinclient++;  // Total clients count
               kk++;
           }


         // Multicasting bytes to all connected clients.
         int kkk =0;
         while(kkk<cntloggedinclient)
         {
           Wificlients[kkk]->write((unsigned char*) &newbuff,len);
           kkk++;    
         }
  • You can't rely on all the data arriving together - your loop which does tree read() will be unreliable. You need to store the WiFiClient object if you want to have multiple connections at the same time. – Mark Smith Apr 6 at 12:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.