Newer
Older
#include <unistd.h>
#include <netdb.h>
#include <regex>
using namespace inaf::oasbo::ConnectionProtocols;
TCPProtocol::TCPProtocol() :
TCPProtocol("127.0.0.1", 9003) {
TCPProtocol::TCPProtocol(std::string ip, int prt) :
srv_sock(-1), cli_sock(-1), ip(ip), port(prt) {
host = ip + ":" + std::to_string(port);
}
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);
pack.copyToBinaryPointer(buff, headerSize);
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 = 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::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;
}
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
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
std::string TCPProtocol::getHost(){
return ip + std::to_string(port);
}
void TCPProtocol::setHost(std::string host){
std::string ip = {};
int port = 0;
if(split_ip_port(host, ip, host)){
setIp(ip);
setPort(port);
}
else{
std::cerr << "Connection Protocol Error: invalid IP address and port format: " << host
<< std::endl;
}
}
void TCPProtocol::setIp(std::string ip ){
std::regex pattern("^(\\d{1,3}\\.){3}\\d{1,3}$");
// Check if the input string matches the expected format
bool ok = true;
if (!std::regex_match(ip, pattern)) {
std::cerr << "Connection Protocol Error: invalid IP address: " << ip
<< ", setting to 127.0.0.1" << std::endl;
ok = false;
this->ip = std::string("127.0.0.1");
}
if(ok)
this->ip = ip;
this->host = ip + std::to_string(port);
}
void TCPProtocol::setPort(int port){
if(port > 1023 && port < 65535)
this->port = port;
else{
std::cerr << "Connection Protocol Error: invalid port: " << port
<< ", setting to 9003" << std::endl;
this->port = 9003;
}
this->host = ip + std::to_string(port);
}
bool 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)) {
return false;
}
// 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);
return true;
}