About Using the EthernetWebServer Library Together with the WebServer Library

https://github.com/khoih-prog/Ethernet_Generic

I am using the library file to write a code that uses both webclient, webserver,
 SF read and write,SD read and write simultaneously. 
Webclient used for download
Webserver mounts LittleFS as a server

https://github.com/amcewen/HttpClient

I found an HttpClient that can be used in conjunction with the EthernetGeneric library
It passes in the HttpClient object to EthernetGeneric
// 引入闪存读写库
#include <FS.h>
#include <LittleFS.h>
// 引入以太网访问库
#include <EthernetClient.h>
#include <HTTPClient.h>

// 声明以太网客户端对象
EthernetClient client;

uint8_t buffsing[10240] = {0}; // 定义下载缓存,在全局变量,使用全局 RAM

void SplitURL(char szUrl[], char szHost[], char szPath[]) { // 分割URL
    int iStart = 0;
    int iEnd = 0;
    int iLen = 0;
    if (strncmp(szUrl, "http://", 7) == 0)
        iStart = 7;
    else if (strncmp(szUrl, "https://", 8) == 0)
        iStart = 8;
    while (szUrl[iStart + iLen] != '\0' && szUrl[iStart + iLen] != '/') {
        iLen++;
    }
    memcpy(szHost, szUrl + iStart, iLen);
    if (strlen(szUrl) - iStart - iLen == 0)
        szPath[0] = '/';
    else
        memcpy(szPath, szUrl + iStart + iLen, strlen(szUrl) - iStart - iLen);
}

bool GetFile(fs::FS &fs, String file_url, const char *tf_url) { // 下载网络文件

    Serial.println("准备下载文件:");

    char szUrl[] = {0};
    char szHost[100] = {0};
    char szPath[1024] = {0};
    strcpy(szUrl, file_url.c_str());
    SplitURL(szUrl, szHost, szPath); // 分割URL

    Serial.print(" - 地址:");
    Serial.print(szHost);
    Serial.print("    路径:");
    Serial.println(szPath);

    // 声明HTTP访问端对象
    HttpClient http(client);
    http.get(szHost, szPath);

    bool log = true;
    int httpCode = http.responseStatusCode();

    Serial.printf(" - [HTTP] GET访问结果: %d\n", httpCode);

    if (httpCode == 200) {

        http.skipResponseHeaders();        // 不用这个取不到Length
        int Length = http.contentLength(); // 读取响应数据字节数

        Serial.print(" - 文件大小 ≈ ");
        Serial.println(GetBytes(Length));

        if (Length > 0) {

            int ms;
            int Leng;
            unsigned long mss;
            unsigned long start; // 取启动时间

            File fe = fs.open(tf_url, "wb+");

            if (!fe) {
                Serial.println(" - 创建下载文件失败");
                log = false;
            } else {

                Serial.println(" - 开始下载文件...");
                ms = 0;
                Leng = 0;
                mss = millis();
                start = millis(); // 开始计时

                while (http.connected() && (Length > 0 || Length == -1)) { // 判断有数据存在

                    size_t size = http.available(); // 获取数据流中字节数

                    if (size) {

                        int c = http.read(buffsing, ((size > sizeof(buffsing)) ? sizeof(buffsing) : size)); // 读取数据

                        if (!fe.write(buffsing, c)) { // 写入文件
                            Serial.println("- 数据写入失败");
                            log = false;
                            break;
                        }

                        Leng += c;
                        Length -= c;

                        ms = (millis() - mss) / 1000.0; // 计时每秒,当前时间减去获取时间

                        delay(1);

                        if ((Length > 0) && (ms >= 1)) { // 大约计算耗时
                            Serial.print(" - 剩余 ≈ ");
                            Serial.print(GetBytes(Length));
                            Serial.print("\t速度 ≈ ");
                            Serial.print(GetBytes(Leng));
                            Serial.println("/S");
                            ms = 0;
                            Leng = 0;
                            mss = millis();
                        }
                        delay(1);
                    }
                }

                start = millis() - start;
                fe.close();
            }

            if (log) {
                Serial.print(" - 文件下载完成, 耗时:");
                Serial.print(start / 1000.0); // 计算耗时
                Serial.println("s");
                Serial.print(" - 文件保存路径:");
                Serial.println(tf_url);
            }

        } else {
            Serial.println(" - 无返回数据");
            log = false;
        }

        http.stop();

    } else {
        Serial.println(" - [HTTP] GET访问失败");
        log = false;
    }
    Serial.println(" - [HTTP] GET访问连接结束");
    return log;
}
But I didn't get a WebServer that I could use with it,
I saw its integration with webserver in the following article

https://forum.arduino.cc/t/is-it-possible-to-do-ota-update-for-the-esp32-using-arduino-ide-2-0-x-via-ethernet-instead-of-wifi/1160693/39

It can be used in conjunction with the EthernetWebServer library supported by 
the EthernetGeneric library
But its webserver is used to connect to WIFI, and I want webserver. h to be used 
through EthernetGeneric's Ethernet
Trigger wireless restart when the following code is not connected to WiFi

#include <WebServer.h>
#include <EthernetWebServer.h>
#include "Ethernet_Generic.h"

EthernetWebServer ethernetServer(80);
WebServer Server(80);

void handle() {
  Server.send(200, "text/plain", "Hello!");
}

void setup() {

  Serial.begin(115200);
  delay(100);

  Ethernet.init (15);
  byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x01}; 
  Ethernet.begin(mac);

  Server.on("/", handle);
  Server.begin();

  Serial.print("HTTPServer is @ IP : ");
  Serial.println(Server.localIP());
}

void loop() {
  Server.handleClient();
}

I would like to use EthernetGeneric's Ethernet instead of WebServer's WiFi to 
replace the EthernetWebServer library as it does not support LittleFS very much

I need LittleFS static files for the WebServer library

SPI2 connection used by EthernetGeneric,Defined in the Ethernet. h example 
of the EthernetGeneric library
Because SD needs to be mounted, SPI2 is used

https://github.com/khoih-prog/EthernetWebServer/blob/master/examples/AdvancedWebServer_ESP32_SPI2/defines.h

#define HSPI_IOMUX_PIN_NUM_MISO 12
#define HSPI_IOMUX_PIN_NUM_MOSI 13
#define HSPI_IOMUX_PIN_NUM_CLK  14
#define HSPI_IOMUX_PIN_NUM_CS   15
#define HSPI_IOMUX_PIN_NUM_WP   2
#define HSPI_IOMUX_PIN_NUM_HD   4

@Deva_Rishi I have recreated the issue,我对占用先前解决的问题表示歉意

what board do you use and what Ethernet module?
for esp32 with W5500 this library is better
https://github.com/khoih-prog/WebServer_ESP32_SC_W5500

我用的Arduino,w5500,IPO IDE using vscode,I have used it before AsyncWebServer_ESP32_W5500,But it only reads and writes bytes of 6kb

If you have created a new thread, send me the link and i can have a look.

Thank you. https://forum.arduino.cc/t/about-using-the-ethernetwebserver-library-together-with-the-webserver-library/1164753

First of all, the SPI ports on an ESP32 are named HSPI & VSPI, and which is 1 or 2 is arbitrary.

The default SPI on a esp32 devkit is VSPI, i use that for ethernet, and use HSPI for the SD card.
HSPI default pin assignment is not working, so alternate pins need to be assigned, and i found that a little easier with SD library

#define HSPI_SCK 17      // these are the pins used for the SD card, 
#define HSPI_MISO 16
#define HSPI_MOSI 4
#define SD_CS 15
#define SPI_FRQ 32000000

SPIClass * hspi = NULL;

setup() {
  hspi = new SPIClass(HSPI);

  hspi->begin(HSPI_SCK, HSPI_MISO, HSPI_MOSI, SD_CS);
  hspi->setFrequency(SPI_FRQ);

  if (!SD.begin(SD_CS, *hspi, SPI_FRQ)) {  // the passing of the pointer to the SPI object is included in SD.h
    Serial.println("Card Mount Failed");    // but i did not find an easy way to do the same with Ethernet_Generic.h
    return;
  }
}
loop {}

That leaves VSPI free for the ethernet shield.
here is a modification to run the webserver on both the ethernet and wifi


#include <WebServer.h>
#include <EthernetWebServer.h>
#include "Ethernet_Generic.h"

EthernetWebServer ethernetServer(80);
WebServer Server(80);

void handle() {
  Server.send(200, "text/plain", "Hello!");
}

void handleEthernet() {
  ethernetServer.send(200, "text/plain", "Hello thru Ethernet !");
}

void setup() {

  Serial.begin(115200);
  delay(100);

  Ethernet.init (15);
  byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x01}; 
  Ethernet.begin(mac);

  ethernetServer.on("/", handleEthernet);
  ethernetServer.begin();

  Server.on("/", handle);
  Server.begin();

  Serial.print("HTTPServer is @ IP : ");
  Serial.println(Server.localIP());
}

void loop() {
  Server.handleClient();
  ethernetServer.handleClient();
}

what does mean ? There should be no difference between using SPIFFS and LittleFS as a source for webpage data.

It is of course always possible to connect both to the same SPI port, and use a different CS/SS pin for the different devices, That would mean switching the CS manually between them for any action since the libraries only switch them on in their initiation. Since it is always clear when you are using the SD card, i would switch that on (LOW) and the ethernet shield off (HIGH) whenever using any card related action, and switch them back after use, but hey an esp32 has 2 port, we can use them both, it will be quicker.

When I use server.serveStatic to bind a static file, 
it cannot be returned with a status code of 1


#include <FS.h>
#include <LittleFS.h>
// 引入以太网服务库
#include <EthernetWebServer.h>

FS *FSiles = &LittleFS;
EthernetWebServer server(80);

String out;
#define MULTIPLY_FACTOR 3.0f
#define STRING_SIZE (8192 * MULTIPLY_FACTOR)

void Web_TainOn() {
    server.handleClient();
}

String getContentType(const String &filename) {
    if (server.hasArg("download")) {
        return "application/octet-stream";
    } else if (filename.endsWith(".htm")) {
        return "text/html";
    } else if (filename.endsWith(".html")) {
        return "text/html";
    } else if (filename.endsWith(".css")) {
        return "text/css";
    } else if (filename.endsWith(".js")) {
        return "application/javascript";
    } else if (filename.endsWith(".png")) {
        return "image/png";
    } else if (filename.endsWith(".gif")) {
        return "image/gif";
    } else if (filename.endsWith(".jpg")) {
        return "image/jpeg";
    } else if (filename.endsWith(".ico")) {
        return "image/x-icon";
    } else if (filename.endsWith(".xml")) {
        return "text/xml";
    } else if (filename.endsWith(".pdf")) {
        return "application/x-pdf";
    } else if (filename.endsWith(".zip")) {
        return "application/x-zip";
    } else if (filename.endsWith(".gz")) {
        return "application/x-gzip";
    }

    return "text/plain";
}

bool handleFileRead(String path) {

    if (path.endsWith("/")) {
        path += "index.html";
    }

    Serial.println("请求路径: " + path);

    String contentType = getContentType(path);

    if (FSiles->exists(path)) {
        File file = FSiles->open(path, "r");
        server.streamFile(file, contentType);
        file.close();
        return true;
    }

    return false;
}

void handleRoot() {

    out.reserve(STRING_SIZE);

    out += "<html><body>\r\n<table><tr><th>INDEX</th><th>DATA</th></tr>";

    for (uint16_t lineIndex = 0; lineIndex < (1000 * MULTIPLY_FACTOR); lineIndex++) {
        out += "<tr><td>";
        out += String(lineIndex);
        out += "</td><td>";
        out += "WiFiWebServer_BigData_ABCDEFGHIJKLMNOPQRSTUVWXYZ</td></tr>";
    }

    out += "</table></body></html>\r\n";
    out += out;
    Serial.print("String Len = ");
    Serial.println(out.length());

    server.send(200, "text/html", out);
}

void listhandle(const char *dirname) {
    File file = FSiles->open(dirname);
    if (!file) {
        return;
    }
    if (!file.isDirectory()) {
        file.close();
        return;
    }
    File fie = file.openNextFile();
    while (fie) {
        if (fie.isDirectory()) {
            listhandle(fie.path());
        } else {
            String url = fie.path();
            url.remove(1, 4);
            //I cannot simply bind static files like webserver
            Serial.println(url);
            server.serveStatic(url.c_str(), LittleFS, fie.path());
        }
        fie = file.openNextFile();
    }
    fie.close();
    file.close();
}

// 开启webserver,挂载网页index.html
void Web_Server() {

    listhandle("/www/");

    server.on("/w/", HTTP_GET, []() {
        if (!handleFileRead(server.uri())) {
            server.send(404, "text/plain", "File Not Found");
        }
    });

    server.on("/cs", handleRoot);

    server.begin();

    Web_TainOn();
}

The serveStatic of EthernetWebServer is not working properly
When I run the library example, the same goes for it, the browser cannot load and 
remains in the loading state
My root file is in the/www/directory of LittleFS
void loop() {
    
    Web_TainOn();//监听客户

    ETH_MainTain();
    if (Ethernet.linkReport() == "NO LINK") {// 监听以太网卡状态
        Serial.println("NO LINK");
    }
    

}

Hmm, is there any particular reason to use LittleFS instead of SPIFFS ?
I mean does using SPIFFS work ?
also

 ETH_MainTain();

I am not sure,but i think this is actually making use of the WiFi - Ethernet bridge, i haven't got that to work, i think it actually requires a specific shield.

That is of course possible, have you looked through the github page of the library to see if there is anything in the discussion about that ? I would need to do a lot of investigating and creating a personal example for that works in one way but not the other, while i don't intend to use this method myself. I recommend you get in touch with the author of the library.

Thank you, I have not contacted the author of the library

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.