diff --git a/examples/Client/Client.ino b/examples/Client/Client.ino index dab1002..6884020 100644 --- a/examples/Client/Client.ino +++ b/examples/Client/Client.ino @@ -23,7 +23,7 @@ uint8_t serverIP[] = ServerIP; // IP-адрес сервера uint8_t buf[512]; // Буфер для передачи данных -unsigned long previousMillis = 0; // Для хранения времени последней отправки +uint32_t previousMillis = 0; // Для хранения времени последней отправки const long interval = 3750; // Интервал отправки данных (1.75 секунды) uint32_t ttt; @@ -34,11 +34,13 @@ EthernetMaketClient client; uint32_t packetCounter = 0; -unsigned long lastActivityTime = 0; // Время последней активности -const long timeout = 300; // Таймаут неактивности в миллисекундах +uint32_t lastActivityTime = 0; // Время последней активности +const uint16_t timeout = 300; // Таймаут неактивности в миллисекундах +uint32_t startConnection = 0; +const uint16_t connectionTimeout = 350; -bool wasConnected = false; -bool dataReady = false; +uint32_t stopStartTime = 0; // Время начала состояния CONNECT_IDLE +const uint32_t stopTimeout = 300; // Таймаут для закрытия сокета в состоянии CONNECT_IDLE void setup() { @@ -48,7 +50,7 @@ void setup() Ethernet.init(); // Настройка Ethernet с указанием статических параметров - Ethernet.begin(mac, localIP, gateway, gateway, subnet); + Ethernet.begin(mac, localIP, subnet, gateway, gateway); // Ethernet.setRtTimeOut(1000 * 10); // Ethernet.setRtCount(3); @@ -56,6 +58,7 @@ void setup() // client.setNoDelayedACK(true); // Не ждать ответа от сервера } +ConnectionStatusSimple connectStatus = CONNECT_IDLE; void loop() { uint32_t currentMillis = millis(); @@ -68,18 +71,96 @@ void loop() if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; - - Serial.println("\n\nConnecting..."); - - client.stop(); // Завершаем предыдущее соединение - dataReady = true; - + // client.stop(); // Завершаем предыдущее соединение + connectStatus = CONNECT_START; } - // Подключаемся к серверу - ConnectionStatusSimple connectStatus; - bool isNonBlocking = true; // Флаг для определения режима подключения + // Подключаемся к серверу + bool isNonBlocking = true; // Флаг для определения режима подключения + + switch (connectStatus) + { + case CONNECT_START: + startConnection = millis(); + connectStatus = CONNECT_CONNECTING; + client.close(); + Serial.println("\n\nConnecting..."); + break; + case CONNECT_CONNECTING: + if (millis() - startConnection >= connectionTimeout) + { + connectStatus = CONNECT_FAIL; + break; + } + break; + case CONNECT_FAIL: + Serial.print("Failed to connect to server in "); + Serial.println(isNonBlocking ? "non-blocking mode" : "blocking mode"); + connectStatus = CONNECT_STOP_START; + break; + case CONNECT_SUCCESS: + Serial.print("Connected to server in "); + Serial.println(isNonBlocking ? "non-blocking mode" : "blocking mode"); + lastActivityTime = millis(); + connectStatus = CONNECT_CONNECTED; + + //! Передача пакетов + for (size_t i = 0; i < 3; i++) + { + client.write((uint8_t *)&packetCounter, sizeof(packetCounter)); + + // Печать отправленного пакета + Serial.print("Sending packet: "); + for (size_t j = 0; j < sizeof(packetCounter); j++) + { + Serial.print(((uint8_t *)&packetCounter)[j], HEX); + Serial.print(" "); + } + Serial.println(); + packetCounter++; + lastActivityTime = millis(); // Обновляем время последней активности для каждого пакета + } + //! Передача завершена + + break; + case CONNECT_CONNECTED: + if (!client.connected()) + { + Serial.println("Client disconnected"); + connectStatus = CONNECT_STOP_START; + } + + // Закрытие соединения по таймеру неактивности + if (client.connected() && (millis() - lastActivityTime > timeout)) + { + Serial.println("Connection closed due to inactivity"); + connectStatus = CONNECT_STOP_START; + } + break; + + case CONNECT_STOP_START: + client.disconnect(); + stopStartTime = millis(); + connectStatus = CONNECT_STOP_WAITING; + break; + + case CONNECT_STOP_WAITING: + if (millis() - stopStartTime >= stopTimeout) + { + client.close(); // Закрываем сокет после таймаута + connectStatus = CONNECT_IDLE; + } + break; + + default: + break; + } + + switch (connectStatus) + { + case CONNECT_START: + case CONNECT_CONNECTING: if (isNonBlocking) { connectStatus = client.connectNonBlock(serverIP, SERVER_PORT); @@ -88,40 +169,13 @@ void loop() { connectStatus = (ConnectionStatusSimple)client.connect(serverIP, SERVER_PORT); } + break; - if (connectStatus == CONNECT_SUCCESS) - { - Serial.print("Connection established in "); - Serial.println(isNonBlocking ? "non-blocking mode" : "blocking mode"); - //! Соединение установлено - lastActivityTime = millis(); // Обновляем время последней активности - for (size_t i = 0; i < 3; i++) - { - client.write((uint8_t *)&packetCounter, sizeof(packetCounter)); + default: + break; + } - // Печать отправленного пакета - Serial.print("Sending packet: "); - for (size_t j = 0; j < sizeof(packetCounter); j++) - { - Serial.print(((uint8_t *)&packetCounter)[j], HEX); - Serial.print(" "); - } - Serial.println(); - packetCounter++; - lastActivityTime = millis(); // Обновляем время последней активности - } - dataReady = false; - connectStatus = CONNECT_IDLE; - } - else - { - Serial.print("Failed to connect to server in "); - Serial.println(isNonBlocking ? "non-blocking mode" : "blocking mode"); - connectStatus = CONNECT_IDLE; - client.stop(); - } - - // Проверка наличия доступных данных от сервера + //? Проверка наличия доступных данных от сервера if (client.available() > 0) { byte response[16]; @@ -158,27 +212,5 @@ void loop() Serial.println("Received an incomplete response"); } } - - // Обновление состояния подключения - if (!wasConnected && client.connected()) - { - wasConnected = true; - } - - if (wasConnected && !client.connected()) - { - wasConnected = false; - client.stop(); - Serial.println("Client disconnected"); - } - - // Закрытие соединения по таймеру неактивности - if (client.connected() && (millis() - lastActivityTime > timeout)) - { - wasConnected = false; - Serial.println("Connection closed due to inactivity"); - client.stop(); - } -} - - + //? ------------------------------------------------- +} \ No newline at end of file diff --git a/src/EthernetMaket.h b/src/EthernetMaket.h index 70a3cc6..be52b61 100644 --- a/src/EthernetMaket.h +++ b/src/EthernetMaket.h @@ -10,7 +10,10 @@ enum ConnectionStatusSimple{ CONNECT_SUCCESS = 1, CONNECT_CONNECTING = 2, CONNECT_START = 3, - CONNECT_IDLE = 4 + CONNECT_IDLE = 4, + CONNECT_CONNECTED = 5, + CONNECT_STOP_START = 6, + CONNECT_STOP_WAITING = 7, }; diff --git a/src/EthernetOverride/TCP.cpp b/src/EthernetOverride/TCP.cpp index 3df472f..567d5bd 100644 --- a/src/EthernetOverride/TCP.cpp +++ b/src/EthernetOverride/TCP.cpp @@ -45,4 +45,42 @@ ConnectionStatusSimple EthernetMaketClient::connectNonBlock(IPAddress ip, uint16 } return CONNECT_CONNECTING; -} \ No newline at end of file +} + +void EthernetMaketClient::disconnect(){ + if (_sock == MAX_SOCK_NUM) + return; + ::disconnect(_sock); +} + +void EthernetMaketClient::close(){ + if (_sock == MAX_SOCK_NUM) + return; + ::close(_sock); + _sock = MAX_SOCK_NUM; +} + +// void EthernetMaketClient::stop() { +// if (_sock == MAX_SOCK_NUM) +// return; + +// // attempt to close the connection gracefully (send a FIN to other side) +// disconnect(_sock); +// unsigned long start = millis(); + +// // wait a second for the connection to close +// uint8_t s; +// do { +// s = status(); +// if (s == SnSR::CLOSED) +// break; // exit the loop +// delay(1); +// } while (millis() - start < 1000); + +// // if it hasn't closed, close it forcefully +// if (status() != SnSR::CLOSED) +// close(_sock); + +// EthernetClass::_server_port[_sock] = 0; +// _sock = MAX_SOCK_NUM; +// } diff --git a/src/EthernetOverride/TCP.h b/src/EthernetOverride/TCP.h index 68eb5c7..9609053 100644 --- a/src/EthernetOverride/TCP.h +++ b/src/EthernetOverride/TCP.h @@ -9,7 +9,9 @@ public: using EthernetClient::EthernetClient; ConnectionStatusSimple connectNonBlock(IPAddress ip, uint16_t port); - + // void stop() override; + void disconnect(); + void close(); }; #endif // __MAKET_TCP_H__ \ No newline at end of file