mirror of
https://github.com/Show-maket/EthernetMaket.git
synced 2026-09-21 04:19:41 +00:00
tcp client
This commit is contained in:
@ -2,8 +2,32 @@
|
||||
#include "utility/w5500.h"
|
||||
#include "utility/socket.h"
|
||||
|
||||
std::vector<EthernetMaketClient*> EthernetMaketClient::instances;
|
||||
|
||||
|
||||
EthernetMaketClient::EthernetMaketClient() {
|
||||
_sock = MAX_SOCK_NUM;
|
||||
instances.push_back(this);
|
||||
}
|
||||
|
||||
EthernetMaketClient::EthernetMaketClient(uint8_t sock) {
|
||||
_sock = sock;
|
||||
instances.push_back(this);
|
||||
}
|
||||
|
||||
EthernetMaketClient::~EthernetMaketClient() {
|
||||
instances.erase(std::remove(instances.begin(), instances.end(), this), instances.end());
|
||||
}
|
||||
|
||||
void EthernetMaketClient::tick() {
|
||||
for (EthernetMaketClient* client : instances) {
|
||||
client->tick_();
|
||||
}
|
||||
}
|
||||
|
||||
ConnectionStatusSimple EthernetMaketClient::connectNonBlock(IPAddress ip, uint16_t port) {
|
||||
|
||||
dstIP = ip;
|
||||
dstPort = port;
|
||||
if (_sock != MAX_SOCK_NUM) {
|
||||
// Serial.println(F("connectNonBlock"));
|
||||
uint8_t status_ = status();
|
||||
@ -47,6 +71,10 @@ ConnectionStatusSimple EthernetMaketClient::connectNonBlock(IPAddress ip, uint16
|
||||
return CONNECT_CONNECTING;
|
||||
}
|
||||
|
||||
bool EthernetMaketClient::isConnected() const {
|
||||
return connectStatus == CONNECT_CONNECTED;
|
||||
}
|
||||
|
||||
void EthernetMaketClient::disconnect(){
|
||||
if (_sock == MAX_SOCK_NUM)
|
||||
return;
|
||||
@ -60,7 +88,7 @@ void EthernetMaketClient::close(){
|
||||
_sock = MAX_SOCK_NUM;
|
||||
}
|
||||
|
||||
void EthernetMaketClient::tick(){
|
||||
void EthernetMaketClient::tick_(){
|
||||
// Подключаемся к серверу
|
||||
switch (connectStatus)
|
||||
{
|
||||
@ -88,26 +116,15 @@ void EthernetMaketClient::tick(){
|
||||
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(); // Обновляем время последней активности для каждого пакета
|
||||
}
|
||||
//! Передача завершена
|
||||
lastActivityTime = millis(); // Обновляем время последней активности
|
||||
|
||||
break;
|
||||
case CONNECT_CONNECTED:
|
||||
|
||||
//! Передача пакетов
|
||||
dataWrite();
|
||||
//! Передача завершена
|
||||
|
||||
if (!connected())
|
||||
{
|
||||
Serial.println("Client disconnected");
|
||||
@ -123,40 +140,58 @@ void EthernetMaketClient::tick(){
|
||||
break;
|
||||
|
||||
case CONNECT_STOP_START:
|
||||
dstIP = IPAddress(0,0,0,0);
|
||||
dstPort = 0;
|
||||
disconnect();
|
||||
stopStartTime = millis();
|
||||
connectStatus = CONNECT_STOP_WAITING;
|
||||
break;
|
||||
|
||||
case CONNECT_STOP_WAITING:
|
||||
if (millis() - stopStartTime >= stopTimeout)
|
||||
{
|
||||
close(); // Закрываем сокет после таймаута
|
||||
connectStatus = CONNECT_IDLE;
|
||||
if (millis() - stopStartTime >= stopTimeout) {
|
||||
close(); // Окончательное закрытие сокета после таймаута
|
||||
connectStatus = (dataSize > 0) ? CONNECT_START : CONNECT_IDLE;
|
||||
} else {
|
||||
// Проверяем состояние сокета для завершения разрыва
|
||||
uint8_t status_ = status();
|
||||
if (status_ == SnSR::CLOSED || status_ == SnSR::CLOSE_WAIT) {
|
||||
close(); // Закрываем при достижении состояния
|
||||
connectStatus = (dataSize > 0) ? CONNECT_START : CONNECT_IDLE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CONNECT_IDLE:
|
||||
if(dataSize){
|
||||
connectStatus = CONNECT_START;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//********************************************************
|
||||
switch (connectStatus)
|
||||
{
|
||||
case CONNECT_START:
|
||||
case CONNECT_CONNECTING:
|
||||
if(dstIP == IPAddress(0,0,0,0) || dstPort == 0)
|
||||
break;
|
||||
|
||||
if (isNonBlocking)
|
||||
{
|
||||
connectStatus = connectNonBlock(serverIP, SERVER_PORT);
|
||||
connectStatus = connectNonBlock(dstIP, dstPort);
|
||||
}
|
||||
else
|
||||
{
|
||||
connectStatus = (ConnectionStatusSimple)connect(serverIP, SERVER_PORT);
|
||||
connectStatus = (ConnectionStatusSimple)connect(dstIP, dstPort);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//********************************************************
|
||||
|
||||
//? Проверка наличия доступных данных от сервера
|
||||
if (available() > 0)
|
||||
@ -197,3 +232,64 @@ void EthernetMaketClient::tick(){
|
||||
}
|
||||
//? -------------------------------------------------
|
||||
}
|
||||
|
||||
bool EthernetMaketClient::dataWrite(){
|
||||
bool ret = false;
|
||||
if(dataSize) {
|
||||
lastActivityTime = millis();
|
||||
if(write((uint8_t *)&dataPtr, dataSize)){
|
||||
dataPtr = nullptr;
|
||||
dataSize = 0; // Очищаем размер данных
|
||||
ret = true;
|
||||
}
|
||||
lastActivityTime = millis();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool EthernetMaketClient::dataWrite(uint8_t* data, uint16_t dataSize, bool override) {
|
||||
if (dataSize == 0 || override || (dataPtr == nullptr && this->dataSize == 0)) {
|
||||
this->dataPtr = data;
|
||||
this->dataSize = dataSize;
|
||||
return dataWrite();
|
||||
} else {
|
||||
Serial.println("Data buffer is not empty. Write operation is ignored.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool EthernetMaketClient::send(uint8_t* data, uint16_t dataSize, IPAddress ip, uint16_t port) {
|
||||
this->dataPtr = data;
|
||||
this->dataSize = dataSize;
|
||||
|
||||
switch (connectStatus) {
|
||||
case CONNECT_CONNECTED:
|
||||
if(dataWrite()){
|
||||
onSendSuccess();
|
||||
}
|
||||
// Если подключено, отправляем данные
|
||||
return true;
|
||||
|
||||
case CONNECT_STOP_WAITING:
|
||||
case CONNECT_STOP_START:
|
||||
return false; // Ожидаем завершения разрыва
|
||||
|
||||
case CONNECT_FAIL:
|
||||
case CONNECT_IDLE:
|
||||
connectNonBlock(ip, port);
|
||||
connectStatus = CONNECT_START; // Начинаем новое подключение
|
||||
return false; // Подключение инициировано
|
||||
|
||||
default:
|
||||
return false; // Пока ждём подключения
|
||||
}
|
||||
}
|
||||
|
||||
void EthernetMaketClient::setOnSendSuccess(const std::function<void()>& callback) {
|
||||
onSendSuccess = callback;
|
||||
}
|
||||
|
||||
void EthernetMaketClient::resetOnSendSuccess() {
|
||||
onSendSuccess = []() {};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user