Add Udp::ReceiveMultiple method

This commit is contained in:
Jérôme Leclercq
2017-07-11 12:11:20 +02:00
parent 2ca844be63
commit b4732d8c17
6 changed files with 189 additions and 0 deletions

View File

@@ -549,6 +549,90 @@ namespace Nz
else // else we received something
senderIp = IpAddressImpl::FromSockAddr(reinterpret_cast<const sockaddr*>(&nameBuffer));
if (from)
*from = IpAddressImpl::FromSockAddr(reinterpret_cast<const sockaddr*>(&nameBuffer));
if (read)
*read = byteRead;
if (error)
*error = SocketError_NoError;
return true;
}
bool SocketImpl::ReceiveMultiple(SocketHandle handle, NetBuffer* buffers, std::size_t bufferCount, IpAddress* from, int* read, SocketError* error)
{
NazaraAssert(handle != InvalidHandle, "Invalid handle");
NazaraAssert(buffers && bufferCount > 0, "Invalid buffers");
StackAllocation memory = NazaraStackAllocation(bufferCount * sizeof(iovec));
struct iovec* sysBuffers = static_cast<struct iovec*>(memory.GetPtr());
for (std::size_t i = 0; i < bufferCount; ++i)
{
sysBuffers[i].iov_base = buffers[i].data;
sysBuffers[i].iov_len = buffers[i].dataLength;
}
struct msghdr msgHdr;
std::memset(&msgHdr, 0, sizeof(msgHdr));
msgHdr.msg_iov = sysBuffers;
msgHdr.msg_iovlen = static_cast<int>(bufferCount);
IpAddressImpl::SockAddrBuffer nameBuffer;
if (from)
{
msgHdr.msg_name = nameBuffer.data();
msgHdr.msg_namelen = static_cast<socklen_t>(nameBuffer.size());
}
int byteRead = recvmsg(handle, &msgHdr, MSG_NOSIGNAL);
if (byteRead == -1)
{
int errorCode = GetLastErrorCode();
if (errorCode == EAGAIN)
errorCode = EWOULDBLOCK;
switch (errorCode)
{
case EWOULDBLOCK:
{
// If we have no data and are not blocking, return true with 0 byte read
recvLength = 0;
senderIp = IpAddress::Invalid;
break;
}
default:
{
if (error)
*error = TranslateErrnoToResolveError(errorCode);
return false; //< Error
}
}
}
else if (byteRead == 0)
{
if (error)
*error = SocketError_ConnectionClosed;
return false; //< Connection closed
}
else // else we received something
senderIp = IpAddressImpl::FromSockAddr(reinterpret_cast<const sockaddr*>(nameBuffer.data()));
#ifdef HAS_MSGHDR_FLAGS
if (msgHdr.msg_flags & MSG_TRUNC)
{
if (error)
*error = SocketError_DatagramSize;
return false;
}
#endif
if (from)
*from = senderIp;

View File

@@ -63,6 +63,7 @@ namespace Nz
static bool Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error);
static bool ReceiveFrom(SocketHandle handle, void* buffer, int length, IpAddress* from, int* read, SocketError* error);
static bool ReceiveMultiple(SocketHandle handle, NetBuffer* buffers, std::size_t bufferCount, IpAddress* from, int* read, SocketError* error);
static bool Send(SocketHandle handle, const void* buffer, int length, int* sent, SocketError* error);
static bool SendMultiple(SocketHandle handle, const NetBuffer* buffers, std::size_t bufferCount, const IpAddress& to, int* sent, SocketError* error);