extern "C" { #include #include #include #include #include #include } #include #include #include #include #include #include UDPClient::UDPClient(void) { sockfd = 0; rmax = 2024; }; std::expected 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 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 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); } };