Fixed TCP packet data corruption in non-blocking mode (#402, #119)

This commit is contained in:
Laurent Gomila 2013-06-17 18:47:16 +02:00
parent 94fc605a70
commit 4d78d02b5c

View File

@ -282,27 +282,28 @@ Socket::Status TcpSocket::send(Packet& packet)
// This means that we have to send the packet size first, so that the
// receiver knows the actual end of the packet in the data stream.
// We allocate an extra memory block so that the size can be sent
// together with the data in a single call. This may seem inefficient,
// but it is actually required to avoid partial send, which could cause
// data corruption on the receiving end.
// Get the data to send from the packet
std::size_t size = 0;
const void* data = packet.onSend(size);
// First send the packet size
// First convert the packet size to network byte order
Uint32 packetSize = htonl(static_cast<Uint32>(size));
Status status = send(reinterpret_cast<const char*>(&packetSize), sizeof(packetSize));
// Make sure that the size was properly sent
if (status != Done)
return status;
// Allocate memory for the data block to send
std::vector<char> blockToSend(sizeof(packetSize) + size);
// Send the packet data
if (packetSize > 0)
{
return send(data, size);
}
else
{
return Done;
}
// Copy the packet size and data into the block to send
std::memcpy(&blockToSend[0], &packetSize, sizeof(packetSize));
if (size > 0)
std::memcpy(&blockToSend[0] + sizeof(packetSize), data, size);
// Send the data block
return send(&blockToSend[0], blockToSend.size());
}