///////////////////////////////////////////////////////
| 203 | |
| 204 | //////////////////////////////////////////////////////////// |
| 205 | Socket::Status UdpSocket::receive(void* data, |
| 206 | std::size_t size, |
| 207 | std::size_t& received, |
| 208 | std::optional<IpAddress>& remoteAddress, |
| 209 | unsigned short& remotePort) |
| 210 | { |
| 211 | // First clear the variables to fill |
| 212 | received = 0; |
| 213 | remoteAddress = std::nullopt; |
| 214 | remotePort = 0; |
| 215 | |
| 216 | // Check the destination buffer |
| 217 | if (!data) |
| 218 | { |
| 219 | err() << "Cannot receive data from the network (the destination buffer is invalid)" << std::endl; |
| 220 | return Status::Error; |
| 221 | } |
| 222 | |
| 223 | // Data that will be filled with the other computer's address |
| 224 | sockaddr_in6 address{}; |
| 225 | |
| 226 | #pragma GCC diagnostic push |
| 227 | #pragma GCC diagnostic ignored "-Wuseless-cast" |
| 228 | // Receive a chunk of bytes |
| 229 | priv::SocketImpl::AddrLength addressSize = sizeof(address); |
| 230 | const int sizeReceived = static_cast<int>( |
| 231 | recvfrom(getNativeHandle(), |
| 232 | static_cast<char*>(data), |
| 233 | static_cast<priv::SocketImpl::Size>(size), |
| 234 | 0, |
| 235 | reinterpret_cast<sockaddr*>(&address), |
| 236 | &addressSize)); |
| 237 | #pragma GCC diagnostic pop |
| 238 | |
| 239 | // Check for errors |
| 240 | if (sizeReceived < 0) |
| 241 | return priv::SocketImpl::getErrorStatus(); |
| 242 | |
| 243 | // Fill the sender information |
| 244 | received = static_cast<std::size_t>(sizeReceived); |
| 245 | |
| 246 | if (address.sin6_family == PF_INET6) |
| 247 | { |
| 248 | remoteAddress = IpAddress( |
| 249 | {address.sin6_addr.s6_addr[0], |
| 250 | address.sin6_addr.s6_addr[1], |
| 251 | address.sin6_addr.s6_addr[2], |
| 252 | address.sin6_addr.s6_addr[3], |
| 253 | address.sin6_addr.s6_addr[4], |
| 254 | address.sin6_addr.s6_addr[5], |
| 255 | address.sin6_addr.s6_addr[6], |
| 256 | address.sin6_addr.s6_addr[7], |
| 257 | address.sin6_addr.s6_addr[8], |
| 258 | address.sin6_addr.s6_addr[9], |
| 259 | address.sin6_addr.s6_addr[10], |
| 260 | address.sin6_addr.s6_addr[11], |
| 261 | address.sin6_addr.s6_addr[12], |
| 262 | address.sin6_addr.s6_addr[13], |