LaurentGomila/SFML — pull request #130 by nitrix (2011-12-07 05:24:37+00:00)
Title: Fix for issue #119

Fix for issue #119: Two packets are sent when using sf::TcpSocket::Send(sf::Packet);

Brainstorm:

* Of course with TCP you need a way to tell how long the data is.

* Sending two packets is a "working" solution, but the TCP/IP overhead is extremely huge. Most games needs short/quick real-time updates and that header is often bigger than the actual data sent...

* The best way to fix this is to prepend the data with an Uint32 telling how long the following data is. (Just like the operator<<(std::string) function does, but for the entire packet data.

* We can't put too much complexity into Packet::onSend() because it's a virtual function.

* Creating a temporary buffer to push the size and also copy the packet's data is counter-intuitive and CPU intensive.

Resolution:

* Every Packet object is now created with a data buffer containing an Uint32 (the size of the packet).

* A few pointers arithmetic have been introduced, but the class internals is fairly simple. Basically, when you call GetDataSize(), you get the internal buffer size minus the Uint32 placeholder... when you read/write data, you do so after the placeholder... basically we're just ignoring the new placeholder, but it's still there in the buffer.

* The placeholder for the size is written only when the packet needs to be sent.

* The current API isn't broken in any way. To achieve that, I needed to do a const_cast<> on Packet::GetData

Result/Note:

I think everything should be fine. UDPSocket doesn't need a size due to datagrams and other functions doesn't use a Packet object.