Files
stvpn/udpclient.cpp
T
2026-04-22 15:02:00 +02:00

97 lines
2.7 KiB
C++

extern "C" {
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <arpa/inet.h>
}
#include <cstring>
#include <expected>
#include <string>
#include <iostream>
#include <resolver.hpp>
#include <udpclient.hpp>
UDPClient::UDPClient(void) {
sockfd = 0;
rmax = 2024;
};
std::expected<void, std::string> UDPClient::Bind(std::string hostname, int nport) {
port = nport;
Resolver resolver;
auto resolveRes = resolver.Resolve(hostname);
if (!resolveRes) {
auto msg = std::format("Cannot resolve hostname {}: {}", hostname, resolveRes.error());
return std::unexpected(msg);
}
auto addr = resolveRes.value();
address = addr.GetAddress();
family = addr.GetFamily();
if ((sockfd = socket(family, SOCK_DGRAM, 0)) < 0) {
int errnocopy = errno;
std::string error = std::strerror(errnocopy);
return std::unexpected("Create socket error: " + error);
}
return {};
}
std::expected<void, std::string> UDPClient::Send(std::string message) {
struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = family;
servaddr.sin_port = htons(port);
servaddr.sin_addr.s_addr = inet_addr(address.c_str());
if (sendto(sockfd, message.data(), message.size(), 0,
(const struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) {
int errnocopy = errno;
std::string error = std::strerror(errnocopy);
return std::unexpected("Send datagram error: " + error);
}
return {};
}
std::expected<std::string, std::string> UDPClient::Recv() {
struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = family;
servaddr.sin_port = htons(port);
servaddr.sin_addr.s_addr = inet_addr(address.c_str());
socklen_t len = sizeof(servaddr);
int rsize = 0;
std::string buffer(rmax, 0);
if((rsize = recvfrom(sockfd, buffer.data(), buffer.size(),
0, (struct sockaddr *)&servaddr, &len)) < 0) {
int errnocopy = errno;
std::string error = std::strerror(errnocopy);
return std::unexpected("Receive datagram error: " + error);
}
std::string reply(buffer.begin(), buffer.begin() + rsize);
return reply;
}
void UDPClient::Close(void) {
if (sockfd > 0) {
close(sockfd);
sockfd = 0;
}
};
UDPClient::~UDPClient(void) {
if (sockfd > 0) {
close(sockfd);
}
};