Files
pip/libs/client_server/piclient_server_client.cpp
2024-09-11 15:44:02 +03:00

126 lines
3.0 KiB
C++

/*
PIP - Platform Independent Primitives
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piclient_server_client.h"
#include "piethernet.h"
#include "piliterals_time.h"
#include "pitime.h"
PIClientServer::Client::Client() {}
PIClientServer::Client::~Client() {
stop();
if (own_tcp) piDeleteSafety(tcp);
}
void PIClientServer::Client::createNew() {
if (tcp) return;
tcp = new PIEthernet(PIEthernet::TCP_Client);
tcp->setParameter(PIEthernet::KeepConnection, true);
own_tcp = true;
init();
}
void PIClientServer::Client::connect(PINetworkAddress addr) {
if (!tcp || !own_tcp) return;
stop();
tcp->connect(addr, true);
tcp->startThreadedRead();
piCout << "Connect to" << addr.toString();
}
void PIClientServer::Client::stop() {
if (!tcp) return;
can_write = false;
tcp->interrupt();
tcp->stopAndWait(10_s);
if (tcp->isThreadedRead()) tcp->terminateThreadedRead();
stream.clear();
}
int PIClientServer::Client::write(const void * d, const size_t s) {
if (!tcp) return -1;
if (!can_write) return 0;
PIMutexLocker guard(write_mutex);
piCout << "... send ...";
stream.send(PIByteArray(d, s));
piCout << "... send ok";
return s;
}
void PIClientServer::Client::enableSymmetricEncryption(const PIByteArray & key) {
if (key.isNotEmpty()) {
stream.setCryptEnabled(true);
stream.setCryptKey(key);
} else
stream.setCryptEnabled(false);
}
void PIClientServer::Client::createForServer(PIEthernet * tcp_) {
tcp = tcp_;
tcp->setParameter(PIEthernet::KeepConnection, false);
init();
}
void PIClientServer::Client::init() {
if (!tcp) return;
CONNECTL(&stream, sendRequest, [this](const PIByteArray & ba) {
if (!can_write) return;
tcp->send(ba);
// piMSleep(1);
});
CONNECTL(&stream, packetReceiveEvent, [this](PIByteArray & ba) {
if (readed_func) readed_func(ba);
readed(ba);
});
CONNECTL(tcp, threadedReadEvent, [this](const uchar * readed, ssize_t size) {
if (!can_write) return;
stream.received(readed, size);
});
CONNECTL(tcp, connected, [this]() {
can_write = true;
piCout << "Connected";
connected();
});
CONNECTL(tcp, disconnected, [this](bool) {
can_write = false;
stream.clear();
piCout << "Disconnected";
disconnected();
});
}
void PIClientServer::Client::destroy() {
can_write = false;
write_mutex.lock();
piDeleteSafety(tcp);
aboutDelete();
piCout << "Destroyed";
}