97 lines
2.7 KiB
C++
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);
|
|
}
|
|
};
|
|
|