Newer
Older
#include <iostream>
#include <string>
#include <sys/socket.h>
#include <unistd.h>
#include <netdb.h>
#include <regex>
#include <limits>
using namespace inaf::oasbo::ConnectionProtocols;
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;
memset(&cliaddr, 0, sizeof(cliaddr));
memset(&srvaddr, 0, sizeof(srvaddr));
// Filling server information
srvaddr.sin_family = AF_INET; // IPv4
srvaddr.sin_addr.s_addr = inet_addr(ip.c_str());
srvaddr.sin_port = htons(this->port);
}
UDPProtocol::UDPProtocol(std::string ip, int port) {
this->host = std::string(ip).append(":").append(std::to_string(port));
this->ip = ip;
this->port = port;
this->srv_sock = -1;
this->cli_sock = -1;
memset(&cliaddr, 0, sizeof(cliaddr));
memset(&srvaddr, 0, sizeof(srvaddr));
// Filling server information
srvaddr.sin_family = AF_INET; // IPv4
srvaddr.sin_addr.s_addr = inet_addr(ip.c_str());
srvaddr.sin_port = htons(this->port);
}
UDPProtocol::~UDPProtocol() {
closeConnectionToClient();
closeConnectionToServer();
}
int UDPProtocol::sendToServer(PacketLib::BasePacket &pack) {
int val = ::sendto(cli_sock, pack.getBinaryPointer(),
pack.getHeaderSize() + pack.getPayloadSize() + pack.getTailSize(),
MSG_CONFIRM, (struct sockaddr*) &srvaddr, sizeof(srvaddr));
int UDPProtocol::receiveHeader(PacketLib::BasePacket &pack) {
size_t bytercv = 0;
uint8_t *buff = new uint8_t[pack.getPacketSize()];
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
while (bytercv < pack.getHeaderSize()) {
int rcv = recvfrom(srv_sock, &buff[bytercv], pack.getPacketSize(),
MSG_WAITFORONE, (struct sockaddr*) &cliaddr, &len);
if (rcv < 0) {
delete buff;
return -1;
}else{
bytercv+=rcv;
}
}
pack.copyToBinaryPointer(buff, bytercv);
delete buff;
return bytercv;
}
int UDPProtocol::receivePayloadAndTail(PacketLib::BasePacket &pack, int offset) {
int toBeReceived = pack.getHeaderSize() + pack.getPayloadSize()
+ pack.getTailSize() - offset;
uint8_t *buff = new uint8_t[toBeReceived];
int bytercv = 0;
socklen_t len = sizeof(cliaddr);
while (bytercv < toBeReceived) {
bytercv += recvfrom(srv_sock, &buff[bytercv], pack.getPacketSize(),
MSG_WAITFORONE, (struct sockaddr*) &cliaddr, &len);
if (bytercv < 0) {
delete buff;
resetPacket(pack, toBeReceived);
return -1;
}
}
if (bytercv != toBeReceived) {
delete buff;
resetPacket(pack, bytercv);
return -1;
} else {
pack.copyToBinaryPointer(buff, toBeReceived);
delete buff;
return bytercv;
}
void UDPProtocol::resetPacket(PacketLib::BasePacket &pack, int bytes) {
uint8_t *buff = new uint8_t[bytes];
std::memset(buff, 0, bytes);
pack.copyToBinaryPointer(buff, bytes);
}
int UDPProtocol::receiveFromClient(PacketLib::BasePacket &pack) {
bool done = false;
int bytercv = 0;
while (!done) {
bytercv = receiveHeader(pack);
if (!isHeaderWellFormed(pack)) { // Reset all
resetPacket(pack, bytercv);
} else {
int payloadSize = receivePayloadAndTail(pack, bytercv);
if(payloadSize < 0){
resetPacket(pack, pack.getPacketSize());
}
else{
bytercv += payloadSize;
done = true;
}
}
}
return bytercv;
}
int UDPProtocol::connectToClient() {
int sockfd;
// Creating socket file descriptor
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation failed");
return -1;
}
// Set timeout to the socket
struct timeval tv;
tv.tv_sec = std::numeric_limits<time_t>::max();
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*) &tv, sizeof tv);
if (bind(sockfd, (const struct sockaddr*) &srvaddr, sizeof(srvaddr)) < 0) {
int UDPProtocol::connectToServer() {
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
printf("Connection made\n");
int UDPProtocol::closeConnectionToClient() {
if (srv_sock != -1) {
::close(srv_sock);
srv_sock = -1;
return 1;
}
int UDPProtocol::closeConnectionToServer() {
if (cli_sock != -1) {
::close(cli_sock);
cli_sock = -1;
}
return 1;
bool UDPProtocol::isConnectedToClient() const {
return srv_sock != -1;
}
bool UDPProtocol::isConnectedToServer() const {
return cli_sock != -1;
bool UDPProtocol::isHeaderWellFormed(PacketLib::BasePacket &pack) {
return true;
}
void UDPProtocol::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);
}