Skip to content
This repository was archived by the owner on Jan 20, 2025. It is now read-only.

Commit a313fc9

Browse files
IMAN4Kme-no-dev
authored andcommitted
Adding Client Server example (#76)
* async client server example added * Rename client.ino to ClientServer.ino * Following Arduino sketch directory rules * prevent magic constants in AsyncClient::errorToString()
1 parent 0450e61 commit a313fc9

File tree

5 files changed

+218
-21
lines changed

5 files changed

+218
-21
lines changed
+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#include <ESP8266WiFi.h>
2+
#include <ESPAsyncTCP.h>
3+
4+
extern "C" {
5+
#include <osapi.h>
6+
#include <os_type.h>
7+
}
8+
9+
#include "config.h"
10+
11+
static os_timer_t intervalTimer;
12+
13+
static void replyToServer(void* arg) {
14+
AsyncClient* client = reinterpret_cast<AsyncClient*>(arg);
15+
16+
// send reply
17+
if (client->space() > 32 && client->canSend()) {
18+
char message[32];
19+
sprintf(message, "this is from %s", WiFi.localIP().toString().c_str());
20+
client->add(message, strlen(message));
21+
client->send();
22+
}
23+
}
24+
25+
/* event callbacks */
26+
static void handleData(void* arg, AsyncClient* client, void *data, size_t len) {
27+
Serial.printf("\n data received from %s \n", client->remoteIP().toString().c_str());
28+
Serial.write((char*)data, len);
29+
30+
os_timer_arm(&intervalTimer, 2000, true); // schedule for reply to server at next 2s
31+
}
32+
33+
void onConnect(void* arg, AsyncClient* client) {
34+
Serial.printf("\n client has been connected to %s on port %d \n", SERVER_HOST_NAME, TCP_PORT);
35+
replyToServer(client);
36+
}
37+
38+
39+
void setup() {
40+
Serial.begin(115200);
41+
delay(20);
42+
43+
// connects to access point
44+
WiFi.mode(WIFI_STA);
45+
WiFi.begin(SSID, PASSWORD);
46+
while (WiFi.status() != WL_CONNECTED) {
47+
Serial.print('.');
48+
delay(500);
49+
}
50+
51+
AsyncClient* client = new AsyncClient;
52+
client->onData(&handleData, client);
53+
client->onConnect(&onConnect, client);
54+
client->connect(SERVER_HOST_NAME, TCP_PORT);
55+
56+
os_timer_disarm(&intervalTimer);
57+
os_timer_setfn(&intervalTimer, &replyToServer, client);
58+
}
59+
60+
void loop() {
61+
62+
}

examples/ClientServer/Client/config.h

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#ifndef CONFIG_H
2+
#define CONFIG_H
3+
4+
/*
5+
* This example demonstrate how to use asynchronous client & server APIs
6+
* in order to establish tcp socket connections in client server manner.
7+
* server is running (on port 7050) on one ESP, acts as AP, and other clients running on
8+
* remaining ESPs acts as STAs. after connection establishment between server and clients
9+
* there is a simple message transfer in every 2s. clients connect to server via it's host name
10+
* (in this case 'esp_server') with help of DNS service running on server side.
11+
*
12+
* Note: default MSS for ESPAsyncTCP is 536 byte and defualt ACK timeout is 5s.
13+
*/
14+
15+
#define SSID "ESP-TEST"
16+
#define PASSWORD "123456789"
17+
18+
#define SERVER_HOST_NAME "esp_server"
19+
20+
#define TCP_PORT 7050
21+
#define DNS_PORT 53
22+
23+
#endif // CONFIG_H
+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#include <ESP8266WiFi.h>
2+
#include <ESPAsyncTCP.h>
3+
#include <DNSServer.h>
4+
#include <vector>
5+
6+
#include "config.h"
7+
8+
static DNSServer DNS;
9+
10+
static std::vector<AsyncClient*> clients; // a list to hold all clients
11+
12+
/* clients events */
13+
static void handleError(void* arg, AsyncClient* client, int8_t error) {
14+
Serial.printf("\n connection error %s from client %s \n", client->errorToString(error), client->remoteIP().toString().c_str());
15+
}
16+
17+
static void handleData(void* arg, AsyncClient* client, void *data, size_t len) {
18+
Serial.printf("\n data received from client %s \n", client->remoteIP().toString().c_str());
19+
Serial.write((char*)data, len);
20+
21+
// reply to client
22+
if (client->space() > 32 && client->canSend()) {
23+
char reply[32];
24+
sprintf(reply, "this is from %s", SERVER_HOST_NAME);
25+
client->add(reply, strlen(reply));
26+
client->send();
27+
}
28+
}
29+
30+
static void handleDisconnect(void* arg, AsyncClient* client) {
31+
Serial.printf("\n client %s disconnected \n", client->remoteIP().toString().c_str());
32+
}
33+
34+
static void handleTimeOut(void* arg, AsyncClient* client, uint32_t time) {
35+
Serial.printf("\n client ACK timeout ip: %s \n", client->remoteIP().toString().c_str());
36+
}
37+
38+
39+
/* server events */
40+
static void handleNewClient(void* arg, AsyncClient* client) {
41+
Serial.printf("\n new client has been connected to server, ip: %s", client->remoteIP().toString().c_str());
42+
43+
// add to list
44+
clients.push_back(client);
45+
46+
// register events
47+
client->onData(&handleData, NULL);
48+
client->onError(&handleError, NULL);
49+
client->onDisconnect(&handleDisconnect, NULL);
50+
client->onTimeout(&handleTimeOut, NULL);
51+
}
52+
53+
void setup() {
54+
Serial.begin(115200);
55+
delay(20);
56+
57+
// create access point
58+
while (!WiFi.softAP(SSID, PASSWORD, 6, false, 15)) {
59+
delay(500);
60+
}
61+
62+
// start dns server
63+
if (!DNS.start(DNS_PORT, SERVER_HOST_NAME, WiFi.softAPIP()))
64+
Serial.printf("\n failed to start dns service \n");
65+
66+
AsyncServer* server = new AsyncServer(TCP_PORT); // start listening on tcp port 7050
67+
server->onClient(&handleNewClient, server);
68+
server->begin();
69+
}
70+
71+
void loop() {
72+
DNS.processNextRequest();
73+
}

examples/ClientServer/Server/config.h

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#ifndef CONFIG_H
2+
#define CONFIG_H
3+
4+
/*
5+
* This example demonstrate how to use asynchronous client & server APIs
6+
* in order to establish tcp socket connections in client server manner.
7+
* server is running (on port 7050) on one ESP, acts as AP, and other clients running on
8+
* remaining ESPs acts as STAs. after connection establishment between server and clients
9+
* there is a simple message transfer in every 2s. clients connect to server via it's host name
10+
* (in this case 'esp_server') with help of DNS service running on server side.
11+
*
12+
* Note: default MSS for ESPAsyncTCP is 536 byte and defualt ACK timeout is 5s.
13+
*/
14+
15+
#define SSID "ESP-TEST"
16+
#define PASSWORD "123456789"
17+
18+
#define SERVER_HOST_NAME "esp_server"
19+
20+
#define TCP_PORT 7050
21+
#define DNS_PORT 53
22+
23+
#endif // CONFIG_H

src/ESPAsyncTCP.cpp

+37-21
Original file line numberDiff line numberDiff line change
@@ -748,27 +748,43 @@ void AsyncClient::ackPacket(struct pbuf * pb){
748748
pbuf_free(pb);
749749
}
750750

751-
const char * AsyncClient::errorToString(int8_t error){
752-
switch(error){
753-
case 0: return "OK";
754-
case -1: return "Out of memory error";
755-
case -2: return "Buffer error";
756-
case -3: return "Timeout";
757-
case -4: return "Routing problem";
758-
case -5: return "Operation in progress";
759-
case -6: return "Illegal value";
760-
case -7: return "Operation would block";
761-
case -8: return "Connection aborted";
762-
case -9: return "Connection reset";
763-
case -10: return "Connection closed";
764-
case -11: return "Not connected";
765-
case -12: return "Illegal argument";
766-
case -13: return "Address in use";
767-
case -14: return "Low-level netif error";
768-
case -15: return "Already connected";
769-
case -55: return "DNS failed";
770-
default: return "UNKNOWN";
771-
}
751+
const char * AsyncClient::errorToString(int8_t error) {
752+
switch (error) {
753+
case ERR_OK:
754+
return "OK";
755+
case ERR_MEM:
756+
return "Out of memory error";
757+
case ERR_BUF:
758+
return "Buffer error";
759+
case ERR_TIMEOUT:
760+
return "Timeout";
761+
case ERR_RTE:
762+
return "Routing problem";
763+
case ERR_INPROGRESS:
764+
return "Operation in progress";
765+
case ERR_VAL:
766+
return "Illegal value";
767+
case ERR_WOULDBLOCK:
768+
return "Operation would block";
769+
case ERR_ABRT:
770+
return "Connection aborted";
771+
case ERR_RST:
772+
return "Connection reset";
773+
case ERR_CLSD:
774+
return "Connection closed";
775+
case ERR_CONN:
776+
return "Not connected";
777+
case ERR_ARG:
778+
return "Illegal argument";
779+
case ERR_USE:
780+
return "Address in use";
781+
case ERR_IF:
782+
return "Low-level netif error";
783+
case ERR_ISCONN:
784+
return "Connection already established";
785+
default:
786+
return "Unknown error";
787+
}
772788
}
773789

774790
const char * AsyncClient::stateToString(){

0 commit comments

Comments
 (0)