Newer
Older
#include <unistd.h>
#include <netdb.h>
#include <regex>
using namespace inaf::oasbo::ConnectionProtocols;
TCPProtocol::TCPProtocol() {
this->host = std::string("127.0.0.1:9003");
std::string port { };
split_ip_port(host, ip, port);
this->port = std::stoi(port);
this->srv_sock = -1;
this->cli_sock = -1;
}
TCPProtocol::TCPProtocol(std::string ip, int prt) {
this->host = std::string(ip).append(":").append(std::to_string(prt));
this->ip = ip;
this->srv_sock = -1;
this->cli_sock = -1;
}
TCPProtocol::~TCPProtocol() {
closeConnectionToClient();
closeConnectionToServer();
int TCPProtocol::sendToServer(PacketLib::BasePacket &pack) {
int val = ::send(cli_sock, pack.getBinaryPointer(),
pack.getHeaderSize() + pack.getPayloadSize() + pack.getTailSize(), MSG_CONFIRM);
return val;
}
int TCPProtocol::receiveFromClient(PacketLib::BasePacket &pack) {
uint8_t *buff = new uint8_t[pack.getPacketStructureByteSize()];
ssize_t rec = ::recv(this->srv_sock, &buff[0], headerSize, MSG_WAITALL);
if(rec == 0){ // connessione chiusa
closeConnectionToClient();
if(rec != headerSize){
delete buff;
return -1;
}
pack.copyToBinaryPointer(buff, headerSize);
if(!pack.isRecognizedHeader()){
resetPacket(pack, headerSize);
delete buff;
return -1;
int to_be_rcv = pack.getPayloadSize() + pack.getTailSize();
rec += ::recv(this->srv_sock, &buff[headerSize],to_be_rcv, MSG_WAITALL);
if(rec != to_be_rcv + headerSize){
resetPacket(pack, headerSize);
delete buff;
return -1;
}
pack.copyToBinaryPointer(&buff[headerSize],
pack.getPayloadSize() + pack.getTailSize(), headerSize);
return m_connectToCli(ip, port);
}
int TCPProtocol::connectToServer() {
return m_connectToSrv(ip, port);
}
int TCPProtocol::closeConnectionToClient() {
if (srv_sock != -1) {
::close(srv_sock);
srv_sock = -1;
}
return 1;
}
int TCPProtocol::closeConnectionToServer() {
if (cli_sock != -1) {
::close(cli_sock);
cli_sock = -1;
}
return 1;
}
bool TCPProtocol::isConnectedToClient() const {
}
bool TCPProtocol::isConnectedToServer() const {
}
int TCPProtocol::m_connectToCli(std::string ip, int port) {
std::cout << "Listening on: " << ip << ":" << port << std::endl;
if(srv_sock == -1){
if ((srv_sock = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
servaddr.sin_addr.s_addr = ::inet_addr(ip.c_str());
servaddr.sin_port = htons(port);
if (bind(srv_sock, (struct sockaddr*) &servaddr, sizeof(servaddr)) < 0) {
std::cerr << "TCP CONNECTION: Bind failed" << std::endl;;
std::cout << "TCP CONNECTION: Waiting for connection" << std::endl;
std::cerr << "TCP CONNECTION: Listen error" << std::endl;;
int newSocket;
int addrlen = sizeof(servaddr);
if ((newSocket = accept(srv_sock, (struct sockaddr*) &servaddr,
(socklen_t*) &addrlen)) < 0) {
std::cerr << "TCP CONNECTION: accept error" << std::endl;;
std::cout << "TCP CONNECTION: Connected" << std::endl;
srv_sock = newSocket;
return srv_sock;
int TCPProtocol::m_connectToSrv(std::string ip, int port) {
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
std::cerr << "TCP CONNECTION: Socket creation error" << std::endl;;
return -1;
}
cli_addr.sin_family = AF_INET;
cli_addr.sin_port = htons(port);
// Convert IPv4 and IPv6 addresses from text to binary form
if (inet_pton(AF_INET, ip.c_str(), &cli_addr.sin_addr) <= 0) {
std::cerr << "TCP CONNECTION: Invalid address/ Address not supported" << std::endl;;
if (connect(sock, (struct sockaddr*) &cli_addr, sizeof(cli_addr)) < 0) {
std::cerr << "TCP CONNECTION: Connection Failed " << std::endl;;
return -1;
}
std::cout << "Connected" << std::endl;
this->cli_sock = sock;
return cli_sock;
void TCPProtocol::split_ip_port(const std::string &ip_port,
std::string &ip_address, std::string &port) {
// Regex pattern to match IP address and port in the format "xxx.xxx.xxx.xxx:xxxx"
std::regex pattern("^(\\d{1,3}\\.){3}\\d{1,3}:(\\d{1,5})$");
// Check if the input string matches the expected format
if (!std::regex_match(ip_port, pattern)) {
std::cerr << "Error: invalid IP address and port format: " << ip_port
<< std::endl;
exit(EXIT_FAILURE);
// Split the input string into IP address and port
int colon_pos = ip_port.find(":");
ip_address = ip_port.substr(0, colon_pos);
port = ip_port.substr(colon_pos + 1);
void TCPProtocol::resetPacket(PacketLib::BasePacket &pack, int bytes) {
uint8_t *buff = new uint8_t[bytes];
std::memset(buff, 0, bytes);
int toBeReset = std::min(static_cast<int>(pack.getPacketStructureByteSize()), bytes);
pack.copyToBinaryPointer(buff, toBeReset);
delete buff;
}
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
class TCPProtocol::Builder {
protected:
TCPProtocol *protocol;
public:
std::string ip_key{"ip"};
std::string port_key{"port"};
Builder() {
this->reset();
}
Builder(std::string ip, int port) {
this->protocol = new TCPProtocol(ip, port);
}
~Builder() {
delete protocol;
}
void reset() {
this->protocol = new TCPProtocol();
}
Builder* configFrom(Configurators::BaseConfigurator *conf) {
std::map<std::string, std::string> params =
conf->readConfig();
if (params.count(ip_key) > 0)
protocol->ip = params[ip_key];
if (params.count(port_key) > 0)
protocol->port = std::stoi(params[port_key]);
return this;
}
Builder* setIp(std::string ip) {
protocol->ip = ip;
return this;
}
Builder* setPort(int port) {
protocol->port = port;
return this;
}
TCPProtocol* getProtocol() {
TCPProtocol *result = this->protocol;
this->reset();
return result;
}
};