Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added server.accept() #257

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2973,6 +2973,112 @@ void loop() {

```

### `server.accept()`

#### Description

The traditional server.available() function would only tell you of a new client after it sent data, which makes some protocols like FTP impossible to properly implement.

The intention is programs will use either available() or accept(), but not both. With available(), the client connection continues to be managed by WiFiServer. You don’t need to keep a client object, since calling available() will give you whatever client has sent data. Simple servers can be written with very little code using available().

With accept(), WiFiServer gives you the client only once, regardless of whether it has sent any data. You must keep track of the connected clients. This requires more code, but you gain more control.


#### Syntax

```
server.accept()

```

#### Parameters
none

#### Returns
- a Client object. If no client has data available for reading, this object will evaluate to false in an if-statement. (WiFiClient).

#### Example

```
#include <SPI.h>
#include <WiFiNINA.h>

char ssid[] = "Network"; // your network SSID (name)
char pass[] = "myPassword"; // your network password

int status = WL_IDLE_STATUS;

// telnet defaults to port 23
WiFiServer server(23);

WiFiClient clients[8];

void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}

// attempt to connect to WiFi network:
status = WiFi.begin(ssid, pass);
if ( status != WL_CONNECTED) {
Serial.println("Couldn't get a WiFi connection");
while(true);
}

// start the server:
server.begin();

Serial.print("Chat server address:");
Serial.println(WiFi.localIP());
}

void loop() {
// check for any new client connecting, and say hello (before any incoming data)
WiFiClient newClient = server.accept();
if (newClient) {
for (byte i=0; i < 8; i++) {
if (!clients[i]) {
Serial.print("We have a new client #");
Serial.println(i);
newClient.print("Hello, client number: ");
newClient.println(i);
// Once we "accept", the client is no longer tracked by WiFiServer
// so we must store it into our list of clients
clients[i] = newClient;
break;
}
}
}

// check for incoming data from all clients
for (byte i=0; i < 8; i++) {
if (clients[i] && clients[i].available() > 0) {
// read bytes from a client
byte buffer[80];
int count = clients[i].read(buffer, 80);
// write the bytes to all other connected clients
for (byte j=0; j < 8; j++) {
if (j != i && clients[j].connected()) {
clients[j].write(buffer, count);
}
}
}
}

// stop any clients which disconnect
for (byte i=0; i < 8; i++) {
if (clients[i] && !clients[i].connected()) {
Serial.print("disconnect client #");
Serial.println(i);
clients[i].stop();
}
}

}
```

### `server.peek()`

#### Description
Expand Down
114 changes: 114 additions & 0 deletions examples/WiFiAdvancedChatServer/WiFiAdvancedChatServer.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
Advanced WiFi Chat Server

A more advanced server that distributes any incoming messages
to all connected clients but the client the message comes from.
To use, telnet to your device's IP address and type.
You can see the client's input in the serial monitor as well.

Circuit:
* Board with NINA module (Arduino MKR WiFi 1010, MKR VIDOR 4000 and UNO WiFi Rev.2)

*/

#include <SPI.h>
#include <WiFiNINA.h>

#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)

int status = WL_IDLE_STATUS;

// telnet defaults to port 23
WiFiServer server(23);

WiFiClient clients[8];

void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}

// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true);
}

String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}

if (fv < "1.5.1") {
Serial.println("Advanced WiFi Chat Server requires firmware version 1.5.1 or higher.");
// don't continue
while (true);
}

// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);

// wait 10 seconds for connection:
delay(10000);
}

// start the server:
server.begin();

Serial.print("Chat server address:");
Serial.println(WiFi.localIP());
}

void loop() {
// check for any new client connecting, and say hello (before any incoming data)
WiFiClient newClient = server.accept();
if (newClient) {
for (byte i=0; i < 8; i++) {
if (!clients[i]) {
Serial.print("We have a new client #");
Serial.println(i);
newClient.print("Hello, client number: ");
newClient.println(i);
// Once we "accept", the client is no longer tracked by WiFiServer
// so we must store it into our list of clients
clients[i] = newClient;
break;
}
}
}

// check for incoming data from all clients
for (byte i=0; i < 8; i++) {
if (clients[i] && clients[i].available() > 0) {
// read bytes from a client
byte buffer[80];
int count = clients[i].read(buffer, 80);
// write the bytes to all other connected clients
for (byte j=0; j < 8; j++) {
if (j != i && clients[j].connected()) {
clients[j].write(buffer, count);
}
}
}
}

// stop any clients which disconnect
for (byte i=0; i < 8; i++) {
if (clients[i] && !clients[i].connected()) {
Serial.print("disconnect client #");
Serial.println(i);
clients[i].stop();
}
}

}
2 changes: 2 additions & 0 deletions examples/WiFiAdvancedChatServer/arduino_secrets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#define SECRET_SSID ""
#define SECRET_PASS ""
6 changes: 6 additions & 0 deletions src/WiFiServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ WiFiClient WiFiServer::available(byte* status)
return WiFiClient(255);
}

WiFiClient WiFiServer::accept()
{
int sock = ServerDrv::availServer(_sock, true);
return WiFiClient(sock);
}

uint8_t WiFiServer::status() {
if (_sock == NO_SOCKET_AVAIL) {
return CLOSED;
Expand Down
1 change: 1 addition & 0 deletions src/WiFiServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class WiFiServer : public Server {
public:
WiFiServer(uint16_t);
WiFiClient available(uint8_t* status = NULL);
WiFiClient accept();
void begin();
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *buf, size_t size);
Expand Down
11 changes: 4 additions & 7 deletions src/utility/server_drv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,20 +256,17 @@ uint16_t ServerDrv::availData(uint8_t sock)
return len;
}

uint8_t ServerDrv::availServer(uint8_t sock)
uint8_t ServerDrv::availServer(uint8_t sock, uint8_t accept)
{
if (!SpiDrv::available()) {
return 255;
}

WAIT_FOR_SLAVE_SELECT();
// Send Command
SpiDrv::sendCmd(AVAIL_DATA_TCP_CMD, PARAM_NUMS_1);
SpiDrv::sendParam(&sock, sizeof(sock), LAST_PARAM);

// pad to multiple of 4
SpiDrv::readChar();
SpiDrv::readChar();
SpiDrv::sendCmd(AVAIL_DATA_TCP_CMD, PARAM_NUMS_2);
SpiDrv::sendParam(&sock, sizeof(sock));
SpiDrv::sendParam(&accept, sizeof(accept), LAST_PARAM);

SpiDrv::spiSlaveDeselect();
//Wait the reply elaboration
Expand Down
2 changes: 1 addition & 1 deletion src/utility/server_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class ServerDrv

static uint16_t availData(uint8_t sock);

static uint8_t availServer(uint8_t sock);
static uint8_t availServer(uint8_t sock, uint8_t accept = false);

static uint8_t checkDataSent(uint8_t sock);

Expand Down
Loading