diff --git a/examples/ClientMultiInstance/ClientMultiInstance.ino b/examples/ClientMultiInstance/ClientMultiInstance.ino new file mode 100644 index 0000000..62371b6 --- /dev/null +++ b/examples/ClientMultiInstance/ClientMultiInstance.ino @@ -0,0 +1,150 @@ +#include "EthernetMaket.h" // Предполагается, что этот файл подключает Ethernet3.h + +#include + +// Настройки для W5500 +#define W5500_CS_PIN PA2 // Пин для CS +#define SOCKET_NUMBER 0 // Используем сокет 0 +#define SERVER_PORT 1337 // Порт на сервере +#define CLIENT_PORT 1337 // Порт клиента + +#define ServerMac {0xDA, 0x7A, 0xFF, 0x00, 0x00, 0x00} +#define ServerIP {192, 168, 254, 254} + +#define IniMac {0xDA, 0x7A, 0xF0, 0x00, 0x00, 0x00} +#define IniIP {192, 168, 254, 253} + +uint8_t gateway[] = {192, 168, 0, 1}; // Шлюз +uint8_t subnet[] = {255, 255, 0, 0}; // Маска подсети + +uint8_t mac[] = IniMac; // MAC-адрес +uint8_t localIP[] = IniIP; // Локальный IP-адрес + +uint8_t serverMac[] = ServerMac; // MAC-адрес сервера +uint8_t serverIP[] = ServerIP; // IP-адрес сервера + +uint8_t buf[512]; // Буфер для передачи данных + +uint32_t previousMillis = 0; // Для хранения времени последней отправки +const long interval = 3750; // Интервал отправки данных (1.75 секунды) +uint32_t ttt; + +EthernetServer server(SERVER_PORT); + + +struct EthernetMaketClientStruct +{ + EthernetMaketClient clientMember; // +}; + +std::map clientMap; + +uint32_t packetCounter = 0; +uint32_t data1; +uint32_t data2; + +void setup() +{ + Serial.begin(115200); + pinMode(LED_BUILTIN, OUTPUT); + Ethernet.setCsPin(W5500_CS_PIN); + Ethernet.init(); + + // Настройка Ethernet с указанием статических параметров + Ethernet.begin(mac, localIP, subnet, gateway, gateway); + + + EthernetMaketClientStruct c1; + EthernetMaketClientStruct c2; + clientMap.insert({1, c1}); + clientMap.insert({2, c2}); +} + +void loop() +{ + EthernetMaketClient::tick(); + uint32_t currentMillis = millis(); + if (currentMillis - ttt > 25) + { + digitalToggle(PC13); + ttt = currentMillis; // Обновляем время + } + + if (currentMillis - previousMillis >= interval) + { + previousMillis = currentMillis; + + Serial.println("connectNonBlock"); + clientMap[1].clientMember.startConnection(serverIP, SERVER_PORT); + clientMap[2].clientMember.startConnection(serverIP, SERVER_PORT); + + + //* for single packets + Serial.print("Sending packet ONE: "); + data1 = packetCounter; + clientMap[1].clientMember.dataWrite((uint8_t *)&data1, sizeof(data1)); + for (size_t j = 0; j < sizeof(data1); j++) + { + Serial.print(((uint8_t *)&data1)[j], HEX); + Serial.print(" "); + } + Serial.println(); + + packetCounter++; + data2 = packetCounter; + + Serial.print("Sending packet TWO: "); + clientMap[2].clientMember.dataWrite((uint8_t *)&data2, sizeof(data2)); + for (size_t j = 0; j < sizeof(data2); j++) + { + Serial.print(((uint8_t *)&data2)[j], HEX); + Serial.print(" "); + } + Serial.println(); + + + + + packetCounter++; + + + } + + +if(clientMap[1].clientMember.available()>0){ + byte response[16]; + int len = clientMap[1].clientMember.read(response, sizeof(response)); + + if (len == 16) + { + // Проверка контрольной суммы + uint8_t checksum = 0; + for (int i = 0; i < 15; i++) + { + checksum += response[i]; + } + + Serial.print("RX: "); + for (int i = 0; i < 16; i++) + { + Serial.print(response[i], HEX); + Serial.print(" "); + } + + if (response[15] == checksum) + { + Serial.println("Checksum is OK"); + } + else + { + Serial.println("Checksum is ERROR"); + } + clientMap[1].clientMember.activityUpdate(); // Обновляем время последней активности + } + else + { + Serial.println("Received an incomplete response"); + } +} + +} \ No newline at end of file diff --git a/examples/Server/Server.ino b/examples/Server/Server.ino index 84fdd13..76a4080 100644 --- a/examples/Server/Server.ino +++ b/examples/Server/Server.ino @@ -25,21 +25,25 @@ void serverHandler(EthernetClient client) byte buf[512]; int len = client.read(buf, sizeof(buf)); - // Обработка каждого 4-байтового пакета - for (int i = 0; i < len; i += 4) - { - int packetLen = min(4, len - i); // Определяем длину текущего пакета - processReceivedData(buf + i, packetLen); - for (uint8_t j = 0; j < 3; j++) - { - sendResponse(client, *(uint32_t *)(buf + i)); - } - packetCounter++; - } + Serial.print("sock: "); + Serial.println(client.getSocketNumber()); + processReceivedData(buf, len); + + // // Обработка каждого 4-байтового пакета + // for (int i = 0; i < len; i += 4) + // { + // int packetLen = min(4, len - i); // Определяем длину текущего пакета + // processReceivedData(buf + i, packetLen); + // for (uint8_t j = 0; j < 3; j++) + // { + // sendResponse(client, *(uint32_t *)(buf + i)); + // } + // packetCounter++; + // } //!----------------- Serial.println("DONE"); - client.stop(); + // client.stop(); Serial.println(); Serial.println(); } diff --git a/src/EthernetOverride/Server.cpp b/src/EthernetOverride/Server.cpp index 99f798c..f3270e3 100644 --- a/src/EthernetOverride/Server.cpp +++ b/src/EthernetOverride/Server.cpp @@ -9,20 +9,20 @@ void EthernetMaketServer::setServerHandler(std::function timeout)) // { diff --git a/src/EthernetOverride/Server.h b/src/EthernetOverride/Server.h index 71b69e4..6fcdd56 100644 --- a/src/EthernetOverride/Server.h +++ b/src/EthernetOverride/Server.h @@ -10,7 +10,7 @@ class EthernetMaketServer : public EthernetServer private: EthernetClient available(); void accept(int sock); - std::function serverHandler = [](EthernetMaketClient sclient) {}; + std::function serverHandler = [](EthernetMaketClient &sclient) {}; bool wasConnected[MAX_SOCK_NUM]; public: diff --git a/src/EthernetOverride/TCP.cpp b/src/EthernetOverride/TCP.cpp index fbb49c8..02a6b61 100644 --- a/src/EthernetOverride/TCP.cpp +++ b/src/EthernetOverride/TCP.cpp @@ -2,30 +2,29 @@ #include "utility/w5500.h" #include "utility/socket.h" -std::list& EthernetMaketClient::getInstances() { - static std::list instances; // Список создаётся при первом доступе - return instances; -} +//////////////////////////////////////////////////////////////// + EthernetMaketClient::EthernetMaketClient() { _sock = MAX_SOCK_NUM; - getInstances().push_back(this); + // Serial.print("SOCK ?? "); Serial.println(_sock); } EthernetMaketClient::EthernetMaketClient(uint8_t sock) { _sock = sock; - getInstances().push_back(this); } -EthernetMaketClient::~EthernetMaketClient() { - getInstances().remove(this); -} +void EthernetMaketClient::tick() + { + forEach( + [](EthernetMaketClient& obj) { + obj.tick_(); + } + ); -void EthernetMaketClient::tick() { - for (EthernetMaketClient* client : getInstances()) { - client->tick_(); - } -} + } + +//////////////////////////////////////////////////////////////// ConnectionStatusSimple EthernetMaketClient::connectNonBlock(IPAddress ip, uint16_t port) { dstIP = ip; @@ -58,6 +57,7 @@ ConnectionStatusSimple EthernetMaketClient::connectNonBlock(IPAddress ip, uint16 uint8_t s = w5500.readSnSR(i); if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT || s == SnSR::CLOSE_WAIT) { _sock = i; + Serial.print("SOCK <- "); Serial.println(_sock); break; } } @@ -85,8 +85,8 @@ ConnectionStatusSimple EthernetMaketClient::connectNonBlock(IPAddress ip, uint16 } -bool EthernetMaketClient::isConnected() const { - return connectStatus == CONNECT_CONNECTED; +bool EthernetMaketClient::canWriteIntoConnection(size_t size) const { + return connectStatus == CONNECT_CONNECTED /* && w5500.getTXFreeSize(_sock) >= size */; } void EthernetMaketClient::disconnect(){ @@ -103,6 +103,11 @@ void EthernetMaketClient::close(){ } void EthernetMaketClient::tick_(){ + if(_sock != MAX_SOCK_NUM && connectStatus!=CONNECT_CONNECTED && connectStatus!=CONNECT_STOP_WAITING&&connectStatus!=CONNECT_CONNECTING){ + Serial.print("tick_() sock = "); Serial.println(_sock); + } + + switch (connectStatus) { case CONNECT_START: @@ -241,9 +246,13 @@ void EthernetMaketClient::dataWrite(uint8_t* data, uint16_t dataSize, bool overr if (this->dataSize == 0 || override) { this->dataPtr = data; this->dataSize = dataSize; - if(isConnected()){ - dataWrite(); - } + activityUpdate(); + Serial.println("Data buffer Saved."); + // if(canWrite(dataSize)){ + // dataWrite(); + // } else { + // Serial.println("W5500 Buffer is full. Write operation is ignored."); + // } } else { Serial.println("Data buffer is not empty. Write operation is ignored."); } @@ -297,6 +306,15 @@ void EthernetMaketClient::startConnection(IPAddress ip, uint16_t port, bool nonB dstPort = port; isNonBlocking = nonBlock; connectStatus = CONNECT_START; + // if (nonBlock) + // { + // connectNonBlock(dstIP, dstPort); + // } + // else + // { + // (ConnectionStatusSimple)connect(dstIP, dstPort); + // } + }; void EthernetMaketClient::activityUpdate(){ @@ -329,3 +347,6 @@ EthernetMaketClient& EthernetMaketClient::operator=(const EthernetMaketClient& o return *this; } +ConnectionStatusSimple EthernetMaketClient::getConnectionStatus() const { + return connectStatus; +} diff --git a/src/EthernetOverride/TCP.h b/src/EthernetOverride/TCP.h index 04bcb3a..a1db481 100644 --- a/src/EthernetOverride/TCP.h +++ b/src/EthernetOverride/TCP.h @@ -4,8 +4,9 @@ #include #include #include "../util/config.h" +#include "InstanceManager.h" -class EthernetMaketClient : public EthernetClient { +class EthernetMaketClient : public EthernetClient, public InstanceManager { protected: uint32_t lastActivityTime = 0; // Время последней активности const uint16_t timeout = 300; // Таймаут неактивности в миллисекундах @@ -25,15 +26,13 @@ protected: bool dataWrite(); - static std::list& getInstances(); // Ленивое создание списка + // static std::list& getInstances(); // Ленивое создание списка - void tick_(); ConnectionStatusSimple connectStatus = CONNECT_IDLE; public: EthernetMaketClient(); EthernetMaketClient(uint8_t sock); - ~EthernetMaketClient(); EthernetMaketClient& operator=(const EthernetMaketClient& other); @@ -46,13 +45,16 @@ public: void disconnect(); void close(); void stop(); - bool isConnected() const; + bool canWriteIntoConnection(size_t = 0) const; static void tick(); + void tick_(); void setOnSendSuccess(const std::function& callback); void resetOnSendSuccess(); + ConnectionStatusSimple getConnectionStatus() const; + void activityUpdate(); };