29 SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
30 if (sock == INVALID_SOCKET) {
31 out_error_code = WSAGetLastError();
36 addr.sin_family = AF_INET;
37 addr.sin_port = htons(
static_cast<u_short
>(req.port));
39 addrinfo hints{}, *res =
nullptr;
40 hints.ai_family = AF_INET;
41 hints.ai_socktype = SOCK_DGRAM;
42 hints.ai_protocol = IPPROTO_UDP;
44 if (getaddrinfo(req.host.c_str(),
nullptr, &hints, &res) != 0 || !res) {
45 out_error_code = WSAGetLastError();
49 addr.sin_addr =
reinterpret_cast<sockaddr_in*
>(res->ai_addr)->sin_addr;
51 const int timeout_ms = req.timeout_ms > 0 ? req.timeout_ms : 5000;
52 DWORD timeout =
static_cast<DWORD
>(timeout_ms);
53 setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
reinterpret_cast<const char*
>(&timeout),
sizeof(timeout));
55 const int send_res = sendto(sock,
56 static_cast<const char*
>(req.send_data),
57 static_cast<int>(req.send_size),
59 reinterpret_cast<sockaddr*
>(&addr),
61 if (send_res == SOCKET_ERROR ||
static_cast<std::size_t
>(send_res) != req.send_size) {
62 out_error_code = WSAGetLastError();
69 int from_len =
sizeof(from);
70 const int recv_res = recvfrom(sock,
71 static_cast<char*
>(req.recv_data),
72 static_cast<int>(req.recv_size),
74 reinterpret_cast<sockaddr*
>(&from),
77 if (recv_res == SOCKET_ERROR ||
static_cast<std::size_t
>(recv_res) != req.recv_size) {
78 out_error_code = WSAGetLastError();