Skip to content
Snippets Groups Projects
Commit e0a19d32 authored by Valerio Pastore's avatar Valerio Pastore
Browse files

updated to new base protocol

parent 0f43845b
No related branches found
No related tags found
No related merge requests found
cmake_minimum_required(VERSION 3.9)
project(TCP_Protocol)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++20")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
option(TCPPROTOCOL_BUILD_SHARED "Build tcpprotocol as a shared library." OFF)
......
Subproject commit 544d785f5accf10762deeaa196d5e907a8dfd7eb
Subproject commit cabf66906db043dd8ce0af7994b14c740401b8e7
......@@ -18,17 +18,32 @@ namespace inaf::oasbo::ConnectionProtocols{
class TCPProtocol : public BaseProtocol{
protected:
int fd_sock;
int srv_sock;
int cli_sock;
std::string ip{};
int port;
void split_ip_port(const std::string& ip_port, std::string& ip, std::string& port);
int m_connectToSrv(std::string ip, int port);
int m_connectToCli(std::string ip, int port);
public:
TCPProtocol(std::string hs, int prt);
~TCPProtocol(){
std::cout << "TCP DISTRUCTOR CALLED" << std::endl;
}
int connectToClient();
int connectToServer();
int sendPacketToSrv(PacketLib::BasePacket &);
int rcvPacketFromCli(PacketLib::BasePacket &);
TCPProtocol(std::string ip, int prt);
TCPProtocol();
~TCPProtocol();
std::string getIp(){return ip;}
int getPort(){ return port;}
void setIp(std::string ip){ this->ip = ip;}
void setPort(int port){this->port = port;}
int connectToServer() override;
int connectToClient() override;
int closeConnectionToServer() override;
int closeConnectionToClient() override;
bool isConnectedToClient() const override;
bool isConnectedToServer() const override;
int receiveFromClient(PacketLib::BasePacket &) override;
int sendToServer(PacketLib::BasePacket &) override;
};
}
......
......@@ -13,17 +13,15 @@ public:
TCPProtocolConfigurator(int argc, char **argv);
TCPProtocolConfigurator();
void setHost(std::string val){this->params["host"] = val;}
void setIp(std::string val){this->params["ip"] = val;}
void setPort(int val){this->params["port"] = std::to_string(val);}
std::map<std::string,std::string> getParams(){return this->params;}
std::string getHost(){return this->params["host"];}
std::string getIp(){return this->params["ip"];}
int getPort(){return stoi(this->params["port"]);}
BaseProtocol * createProtocol();
ConnectionProtocols::TCPProtocol * createTCPProtocol();
void createTCPProtocol(TCPProtocol &);
void printConfiguration(){
......
#include <iostream>
#include <string>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <fstream>
#include <map>
#include <unistd.h>
#include <netdb.h>
#include <regex>
#include <TCP_Protocol.h>
using namespace inaf::oasbo::ConnectionProtocols;
TCPProtocol::TCPProtocol(std::string hs, int prt){
this->host = hs;
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->port = prt;
fd_sock = 0;
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.getMaxPacketSize()];
size_t rec = ::recv(this->srv_sock, &buff[0], headerSize, MSG_WAITALL);
pack.copyToBinaryPointer(buff, headerSize);
if (rec == headerSize) {
rec += ::recv(this->srv_sock, &buff[headerSize],
pack.getPayloadSize() + pack.getTailSize(), MSG_WAITALL);
pack.copyToBinaryPointer(&buff[headerSize],
pack.getPayloadSize() + pack.getTailSize(), headerSize);
}
delete buff;
return rec;
}
/*
* Implementation of the BaseSocket connect for the TCP protocol
*
* @return file_descriptor [-1 error]
*/
int TCPProtocol::connectToClient() {
int sockfd, newSocket;
struct sockaddr_in servaddr;
int addrlen = sizeof(servaddr);
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;
// Creating socket file descriptor
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == 0){
if ((srv_sock = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
return -1;
}
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons( port );
if (bind(sockfd, (struct sockaddr *)&servaddr,sizeof(servaddr))<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;
if (listen(sockfd, 1) < 0){
if (listen(srv_sock, 1) < 0) {
perror("listen error");
return -1;
}
if ((newSocket = accept(sockfd, (struct sockaddr *)&servaddr,(socklen_t*)&addrlen))<0){
int newSocket;
int addrlen = sizeof(servaddr);
if ((newSocket = accept(srv_sock, (struct sockaddr*) &servaddr,
(socklen_t*) &addrlen)) < 0) {
perror("accept error");
return -1;
}
::close(srv_sock);
std::cout << "Connected" << std::endl;
this->fd_sock = newSocket;
return newSocket;
srv_sock = newSocket;
return srv_sock;
}
int TCPProtocol::connectToServer(){
int TCPProtocol::m_connectToSrv(std::string ip, int port) {
int sock = 0;
struct sockaddr_in cli_addr;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0){
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("\n Socket creation error \n");
return -1;
}
......@@ -63,42 +125,35 @@ int TCPProtocol::connectToServer(){
cli_addr.sin_port = htons(port);
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, host.c_str(), &cli_addr.sin_addr)<=0){
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){
if (connect(sock, (struct sockaddr*) &cli_addr, sizeof(cli_addr)) < 0) {
printf("\nConnection Failed \n");
return -1;
}
std::cout << "Connected" << std::endl;
this->fd_sock = sock;
return sock;
this->cli_sock = sock;
return cli_sock;
}
/*
* Implementation of the BaseSocket readPacket for the TCP protocol
*
* @param pack: address of the packet object
* @param buff: buffer to write the read bytes
*
* @return number of bytes received [-1 error, 0 done]
*/
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})$");
int TCPProtocol::rcvPacketFromCli(PacketLib::BasePacket &pack){
size_t headerSize = pack.getHeaderSize();
uint8_t *buff = new uint8_t[pack.getMaxPacketSize()];
size_t rec = recv(this->fd_sock, &buff[0], headerSize, MSG_WAITALL);
pack.copyToBinaryPointer(buff, headerSize);
if(rec == headerSize){
rec+= recv(this->fd_sock, &buff[headerSize], pack.getPayloadSize() + pack.getTailSize(), MSG_WAITALL);
pack.copyToBinaryPointer(&buff[headerSize], pack.getPayloadSize() + pack.getTailSize(), headerSize);
// 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);
}
delete buff;
return rec;
}
int TCPProtocol::sendPacketToSrv(PacketLib::BasePacket &pack){
int val = send(fd_sock, pack.getBinaryPointer(), pack.getHeaderSize()+pack.getPayloadSize()+pack.getTailSize(), MSG_CONFIRM);
return val;
// 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);
}
......@@ -4,7 +4,7 @@
using namespace inaf::oasbo::ConnectionProtocols;
TCPProtocolConfigurator::TCPProtocolConfigurator(){
setHost("127.0.0.1");
setIp("127.0.0.1");
setPort(9003);
}
......@@ -13,15 +13,15 @@ TCPProtocolConfigurator::TCPProtocolConfigurator(int argc, char ** argv){
try {
TCLAP::CmdLine cmd("Usage Description WIP", ' ', "1");
cmd.ignoreUnmatched(true);
TCLAP::ValueArg<std::string> host("","ip","Host IP address",false,"127.0.0.1","X.X.X.X");
cmd.add( host );
TCLAP::ValueArg<std::string> ip("","ip","Host IP address",false,"127.0.0.1","X.X.X.X");
cmd.add( ip );
TCLAP::ValueArg<std::string> port("","port","listening port of the host",false,"9003","int");
cmd.add( port );
cmd.parse( argc, argv );
setHost(host.getValue());
setIp(ip.getValue());
setPort(std::stoi(port.getValue()));
}catch (TCLAP::ArgException &e){ // catch any exceptions
......@@ -31,15 +31,10 @@ TCPProtocolConfigurator::TCPProtocolConfigurator(int argc, char ** argv){
}
BaseProtocol * TCPProtocolConfigurator::createProtocol(){
return new TCPProtocol(getHost(),getPort());
return new TCPProtocol(getIp(),getPort());
}
TCPProtocol * TCPProtocolConfigurator::createTCPProtocol(){
return new TCPProtocol(getHost(),getPort());
}
void TCPProtocolConfigurator::createTCPProtocol(TCPProtocol & prot){
prot.setHost(getHost());
prot.setPort(getPort());
return new TCPProtocol(getIp(),getPort());
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment