mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-29 05:21:37 +03:00
Stream::send() (#6979)
This commit is contained in:
141
libraries/ESP8266WiFi/examples/WiFiEcho/WiFiEcho.ino
Normal file
141
libraries/ESP8266WiFi/examples/WiFiEcho/WiFiEcho.ino
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
WiFiEcho - Echo server
|
||||
|
||||
released to public domain
|
||||
*/
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
#include <PolledTimeout.h>
|
||||
#include <algorithm> // std::min
|
||||
|
||||
#ifndef STASSID
|
||||
#define STASSID "your-ssid"
|
||||
#define STAPSK "your-password"
|
||||
#endif
|
||||
|
||||
constexpr int port = 23;
|
||||
|
||||
WiFiServer server(port);
|
||||
WiFiClient client;
|
||||
|
||||
constexpr size_t sizes [] = { 0, 512, 384, 256, 128, 64, 16, 8, 4 };
|
||||
constexpr uint32_t breathMs = 200;
|
||||
esp8266::polledTimeout::oneShotFastMs enoughMs(breathMs);
|
||||
esp8266::polledTimeout::periodicFastMs test(2000);
|
||||
int t = 1; // test (1, 2 or 3, see below)
|
||||
int s = 0; // sizes[] index
|
||||
|
||||
void setup() {
|
||||
|
||||
Serial.begin(115200);
|
||||
Serial.println(ESP.getFullVersion());
|
||||
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(STASSID, STAPSK);
|
||||
Serial.print("\nConnecting to ");
|
||||
Serial.println(STASSID);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.print('.');
|
||||
delay(500);
|
||||
}
|
||||
Serial.println();
|
||||
Serial.print("connected, address=");
|
||||
Serial.println(WiFi.localIP());
|
||||
|
||||
server.begin();
|
||||
|
||||
MDNS.begin("echo23");
|
||||
|
||||
Serial.printf("Ready!\n"
|
||||
"- Use 'telnet/nc echo23.local %d' to try echo\n\n"
|
||||
"- Use 'python3 echo-client.py' bandwidth meter to compare transfer APIs\n\n"
|
||||
" and try typing 1, 1, 1, 2, 2, 2, 3, 3, 3 on console during transfers\n\n",
|
||||
port);
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
|
||||
MDNS.update();
|
||||
|
||||
static uint32_t tot = 0;
|
||||
static uint32_t cnt = 0;
|
||||
if (test && cnt) {
|
||||
Serial.printf("measured-block-size=%u min-free-stack=%u", tot / cnt, ESP.getFreeContStack());
|
||||
if (t == 2 && sizes[s]) {
|
||||
Serial.printf(" (blocks: at most %d bytes)", sizes[s]);
|
||||
}
|
||||
if (t == 3 && sizes[s]) {
|
||||
Serial.printf(" (blocks: exactly %d bytes)", sizes[s]);
|
||||
}
|
||||
if (t == 3 && !sizes[s]) {
|
||||
Serial.printf(" (blocks: any size)");
|
||||
}
|
||||
Serial.printf("\n");
|
||||
}
|
||||
|
||||
//check if there are any new clients
|
||||
if (server.hasClient()) {
|
||||
client = server.available();
|
||||
Serial.println("New client");
|
||||
}
|
||||
|
||||
if (Serial.available()) {
|
||||
s = (s + 1) % (sizeof(sizes) / sizeof(sizes[0]));
|
||||
switch (Serial.read()) {
|
||||
case '1': if (t != 1) s = 0; t = 1; Serial.println("byte-by-byte (watch then press 2 or 3)"); break;
|
||||
case '2': if (t != 2) s = 1; t = 2; Serial.printf("through buffer (watch then press 2 again, or 1 or 3)\n"); break;
|
||||
case '3': if (t != 3) s = 0; t = 3; Serial.printf("direct access (watch then press 3 again, or 1 or 2)\n"); break;
|
||||
}
|
||||
tot = cnt = 0;
|
||||
ESP.resetFreeContStack();
|
||||
}
|
||||
|
||||
enoughMs.reset(breathMs);
|
||||
|
||||
if (t == 1) {
|
||||
// byte by byte
|
||||
while (client.available() && client.availableForWrite() && !enoughMs) {
|
||||
// working char by char is not efficient
|
||||
client.write(client.read());
|
||||
cnt++;
|
||||
tot += 1;
|
||||
}
|
||||
}
|
||||
|
||||
else if (t == 2) {
|
||||
// block by block through a local buffer (2 copies)
|
||||
while (client.available() && client.availableForWrite() && !enoughMs) {
|
||||
size_t maxTo = std::min(client.available(), client.availableForWrite());
|
||||
maxTo = std::min(maxTo, sizes[s]);
|
||||
uint8_t buf[maxTo];
|
||||
size_t tcp_got = client.read(buf, maxTo);
|
||||
size_t tcp_sent = client.write(buf, tcp_got);
|
||||
if (tcp_sent != maxTo) {
|
||||
Serial.printf("len mismatch: available:%zd tcp-read:%zd serial-write:%zd\n", maxTo, tcp_got, tcp_sent);
|
||||
}
|
||||
tot += tcp_sent;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
else if (t == 3) {
|
||||
// stream to print, possibly with only one copy
|
||||
if (sizes[s]) {
|
||||
tot += client.sendSize(&client, sizes[s]);
|
||||
} else {
|
||||
tot += client.sendAll(&client);
|
||||
}
|
||||
cnt++;
|
||||
|
||||
switch (client.getLastSendReport()) {
|
||||
case Stream::Report::Success: break;
|
||||
case Stream::Report::TimedOut: Serial.println("Stream::send: timeout"); break;
|
||||
case Stream::Report::ReadError: Serial.println("Stream::send: read error"); break;
|
||||
case Stream::Report::WriteError: Serial.println("Stream::send: write error"); break;
|
||||
case Stream::Report::ShortOperation: Serial.println("Stream::send: short transfer"); break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
49
libraries/ESP8266WiFi/examples/WiFiEcho/echo-client.py
Executable file
49
libraries/ESP8266WiFi/examples/WiFiEcho/echo-client.py
Executable file
@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import asyncio
|
||||
|
||||
# 512 bytes
|
||||
message = bytearray(512);
|
||||
bufsize=len(message)
|
||||
print('message len=', bufsize)
|
||||
|
||||
global recv
|
||||
recv = 0
|
||||
|
||||
async def tcp_echo_open (ip, port):
|
||||
return await asyncio.open_connection(ip, port)
|
||||
|
||||
async def tcp_echo_sender(message, writer):
|
||||
print('Writer started')
|
||||
while True:
|
||||
writer.write(message)
|
||||
await writer.drain()
|
||||
|
||||
async def tcp_echo_receiver(message, reader):
|
||||
global recv
|
||||
print('Reader started')
|
||||
while True:
|
||||
data = ''.encode('utf8')
|
||||
while len(data) < bufsize:
|
||||
data += await reader.read(bufsize - len(data))
|
||||
recv += len(data);
|
||||
if data != message:
|
||||
print('error')
|
||||
|
||||
async def tcp_stat():
|
||||
global recv
|
||||
dur = 0
|
||||
loopsec = 2
|
||||
while True:
|
||||
last = recv
|
||||
await asyncio.sleep(loopsec) # drifting
|
||||
dur += loopsec
|
||||
print('BW=', (recv - last) * 2 * 8 / 1024 / loopsec, 'Kibits/s avg=', recv * 2 * 8 / 1024 / dur)
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
reader, writer = loop.run_until_complete(tcp_echo_open('echo23.local', 23))
|
||||
loop.create_task(tcp_echo_receiver(message, reader))
|
||||
loop.create_task(tcp_echo_sender(message, writer))
|
||||
loop.create_task(tcp_stat())
|
||||
loop.run_forever()
|
Reference in New Issue
Block a user