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) {
size_t headerSize = pack.getHeaderSize();
uint8_t *buff = new uint8_t[pack.getPacketStructureByteSize()];
size_t rec = ::recv(this->srv_sock, &buff[0], headerSize,0);
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,0);
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 {
return srv_sock != -1;
}
bool TCPProtocol::isConnectedToServer() const {
return cli_sock != -1;
}
int TCPProtocol::m_connectToCli(std::string ip, int port) {
std::cout << "Listening on: " << ip << ":" << port << std::endl;
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) {
perror("bind failed");
return -1;
}
std::cout << "Waiting for connection" << std::endl;
int newSocket;
int addrlen = sizeof(servaddr);
if ((newSocket = accept(srv_sock, (struct sockaddr*) &servaddr,
(socklen_t*) &addrlen)) < 0) {
srv_sock = newSocket;
return srv_sock;
int TCPProtocol::m_connectToSrv(std::string ip, int port) {
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("\n Socket creation error \n");
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) {
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr*) &cli_addr, sizeof(cli_addr)) < 0) {
printf("\nConnection Failed \n");
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;
}