Skip to content

Commit 97c4d94

Browse files
committed
added server.accept()
1 parent 12c33f1 commit 97c4d94

File tree

7 files changed

+234
-8
lines changed

7 files changed

+234
-8
lines changed

docs/api.md

+106
Original file line numberDiff line numberDiff line change
@@ -2973,6 +2973,112 @@ void loop() {
29732973
29742974
```
29752975

2976+
### `server.accept()`
2977+
2978+
#### Description
2979+
2980+
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.
2981+
2982+
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().
2983+
2984+
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.
2985+
2986+
2987+
#### Syntax
2988+
2989+
```
2990+
server.accept()
2991+
2992+
```
2993+
2994+
#### Parameters
2995+
none
2996+
2997+
#### Returns
2998+
- a Client object. If no client has data available for reading, this object will evaluate to false in an if-statement. (WiFiClient).
2999+
3000+
#### Example
3001+
3002+
```
3003+
#include <SPI.h>
3004+
#include <WiFiNINA.h>
3005+
3006+
char ssid[] = "Network"; // your network SSID (name)
3007+
char pass[] = "myPassword"; // your network password
3008+
3009+
int status = WL_IDLE_STATUS;
3010+
3011+
// telnet defaults to port 23
3012+
WiFiServer server(23);
3013+
3014+
WiFiClient clients[8];
3015+
3016+
void setup() {
3017+
//Initialize serial and wait for port to open:
3018+
Serial.begin(9600);
3019+
while (!Serial) {
3020+
; // wait for serial port to connect. Needed for native USB port only
3021+
}
3022+
3023+
// attempt to connect to WiFi network:
3024+
status = WiFi.begin(ssid, pass);
3025+
if ( status != WL_CONNECTED) {
3026+
Serial.println("Couldn't get a WiFi connection");
3027+
while(true);
3028+
}
3029+
3030+
// start the server:
3031+
server.begin();
3032+
3033+
Serial.print("Chat server address:");
3034+
Serial.println(WiFi.localIP());
3035+
}
3036+
3037+
void loop() {
3038+
// check for any new client connecting, and say hello (before any incoming data)
3039+
WiFiClient newClient = server.accept();
3040+
if (newClient) {
3041+
for (byte i=0; i < 8; i++) {
3042+
if (!clients[i]) {
3043+
Serial.print("We have a new client #");
3044+
Serial.println(i);
3045+
newClient.print("Hello, client number: ");
3046+
newClient.println(i);
3047+
// Once we "accept", the client is no longer tracked by WiFiServer
3048+
// so we must store it into our list of clients
3049+
clients[i] = newClient;
3050+
break;
3051+
}
3052+
}
3053+
}
3054+
3055+
// check for incoming data from all clients
3056+
for (byte i=0; i < 8; i++) {
3057+
if (clients[i] && clients[i].available() > 0) {
3058+
// read bytes from a client
3059+
byte buffer[80];
3060+
int count = clients[i].read(buffer, 80);
3061+
// write the bytes to all other connected clients
3062+
for (byte j=0; j < 8; j++) {
3063+
if (j != i && clients[j].connected()) {
3064+
clients[j].write(buffer, count);
3065+
}
3066+
}
3067+
}
3068+
}
3069+
3070+
// stop any clients which disconnect
3071+
for (byte i=0; i < 8; i++) {
3072+
if (clients[i] && !clients[i].connected()) {
3073+
Serial.print("disconnect client #");
3074+
Serial.println(i);
3075+
clients[i].stop();
3076+
}
3077+
}
3078+
3079+
}
3080+
```
3081+
29763082
### `server.peek()`
29773083

29783084
#### Description
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
Advanced WiFi Chat Server
3+
4+
A more advanced server that distributes any incoming messages
5+
to all connected clients but the client the message comes from.
6+
To use, telnet to your device's IP address and type.
7+
You can see the client's input in the serial monitor as well.
8+
9+
Circuit:
10+
* Board with NINA module (Arduino MKR WiFi 1010, MKR VIDOR 4000 and UNO WiFi Rev.2)
11+
12+
*/
13+
14+
#include <SPI.h>
15+
#include <WiFiNINA.h>
16+
17+
#include "arduino_secrets.h"
18+
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
19+
char ssid[] = SECRET_SSID; // your network SSID (name)
20+
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
21+
22+
int status = WL_IDLE_STATUS;
23+
24+
// telnet defaults to port 23
25+
WiFiServer server(23);
26+
27+
WiFiClient clients[8];
28+
29+
void setup() {
30+
//Initialize serial and wait for port to open:
31+
Serial.begin(9600);
32+
while (!Serial) {
33+
; // wait for serial port to connect. Needed for native USB port only
34+
}
35+
36+
// check for the WiFi module:
37+
if (WiFi.status() == WL_NO_MODULE) {
38+
Serial.println("Communication with WiFi module failed!");
39+
// don't continue
40+
while (true);
41+
}
42+
43+
String fv = WiFi.firmwareVersion();
44+
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
45+
Serial.println("Please upgrade the firmware");
46+
}
47+
48+
if (fv < "1.5.1") {
49+
Serial.println("Advanced WiFi Chat Server requires firmware version 1.5.1 or higher.");
50+
// don't continue
51+
while (true);
52+
}
53+
54+
// attempt to connect to WiFi network:
55+
while (status != WL_CONNECTED) {
56+
Serial.print("Attempting to connect to SSID: ");
57+
Serial.println(ssid);
58+
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
59+
status = WiFi.begin(ssid, pass);
60+
61+
// wait 10 seconds for connection:
62+
delay(10000);
63+
}
64+
65+
// start the server:
66+
server.begin();
67+
68+
Serial.print("Chat server address:");
69+
Serial.println(WiFi.localIP());
70+
}
71+
72+
void loop() {
73+
// check for any new client connecting, and say hello (before any incoming data)
74+
WiFiClient newClient = server.accept();
75+
if (newClient) {
76+
for (byte i=0; i < 8; i++) {
77+
if (!clients[i]) {
78+
Serial.print("We have a new client #");
79+
Serial.println(i);
80+
newClient.print("Hello, client number: ");
81+
newClient.println(i);
82+
// Once we "accept", the client is no longer tracked by WiFiServer
83+
// so we must store it into our list of clients
84+
clients[i] = newClient;
85+
break;
86+
}
87+
}
88+
}
89+
90+
// check for incoming data from all clients
91+
for (byte i=0; i < 8; i++) {
92+
if (clients[i] && clients[i].available() > 0) {
93+
// read bytes from a client
94+
byte buffer[80];
95+
int count = clients[i].read(buffer, 80);
96+
// write the bytes to all other connected clients
97+
for (byte j=0; j < 8; j++) {
98+
if (j != i && clients[j].connected()) {
99+
clients[j].write(buffer, count);
100+
}
101+
}
102+
}
103+
}
104+
105+
// stop any clients which disconnect
106+
for (byte i=0; i < 8; i++) {
107+
if (clients[i] && !clients[i].connected()) {
108+
Serial.print("disconnect client #");
109+
Serial.println(i);
110+
clients[i].stop();
111+
}
112+
}
113+
114+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#define SECRET_SSID ""
2+
#define SECRET_PASS ""

src/WiFiServer.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ WiFiClient WiFiServer::available(byte* status)
8080
return WiFiClient(255);
8181
}
8282

83+
WiFiClient WiFiServer::accept()
84+
{
85+
int sock = ServerDrv::availServer(_sock, true);
86+
return WiFiClient(sock);
87+
}
88+
8389
uint8_t WiFiServer::status() {
8490
if (_sock == NO_SOCKET_AVAIL) {
8591
return CLOSED;

src/WiFiServer.h

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class WiFiServer : public Server {
3838
public:
3939
WiFiServer(uint16_t);
4040
WiFiClient available(uint8_t* status = NULL);
41+
WiFiClient accept();
4142
void begin();
4243
virtual size_t write(uint8_t);
4344
virtual size_t write(const uint8_t *buf, size_t size);

src/utility/server_drv.cpp

+4-7
Original file line numberDiff line numberDiff line change
@@ -256,20 +256,17 @@ uint16_t ServerDrv::availData(uint8_t sock)
256256
return len;
257257
}
258258

259-
uint8_t ServerDrv::availServer(uint8_t sock)
259+
uint8_t ServerDrv::availServer(uint8_t sock, uint8_t accept)
260260
{
261261
if (!SpiDrv::available()) {
262262
return 255;
263263
}
264264

265265
WAIT_FOR_SLAVE_SELECT();
266266
// Send Command
267-
SpiDrv::sendCmd(AVAIL_DATA_TCP_CMD, PARAM_NUMS_1);
268-
SpiDrv::sendParam(&sock, sizeof(sock), LAST_PARAM);
269-
270-
// pad to multiple of 4
271-
SpiDrv::readChar();
272-
SpiDrv::readChar();
267+
SpiDrv::sendCmd(AVAIL_DATA_TCP_CMD, PARAM_NUMS_2);
268+
SpiDrv::sendParam(&sock, sizeof(sock));
269+
SpiDrv::sendParam(&accept, sizeof(accept), LAST_PARAM);
273270

274271
SpiDrv::spiSlaveDeselect();
275272
//Wait the reply elaboration

src/utility/server_drv.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class ServerDrv
5757

5858
static uint16_t availData(uint8_t sock);
5959

60-
static uint8_t availServer(uint8_t sock);
60+
static uint8_t availServer(uint8_t sock, uint8_t accept = false);
6161

6262
static uint8_t checkDataSent(uint8_t sock);
6363

0 commit comments

Comments
 (0)