Hi everyone! I've been creating a game that utilizes SDL_net to send and receive TCP messages from different clients, but I've recently run into a problem. When a user drags the window (created with SDL), the program pauses because of Windows. However, I've noticed that all of the packets that have been sent to that client become truncated while the window is being dragged because the game is being paused. For example, if I sent a packet containing "Hello world" the client would receive "llo world" after they stop dragging the window.
Members - Reputation: 119
Posted 20 April 2013 - 11:28 PM
Members - Reputation: 2032
Posted 21 April 2013 - 02:41 AM
TCP is a stream protocol, it doesn't have the concept of packets. As the SDL docu states, SDLNet_TCP_Recv(socket, packetBuffer, bufferSize) does not necessarily recieve bufferSize bytes of data. The amount of data recieved is returned in the return value.
If you want to build a packet based protocol on top of tcp, you must implement mechanisms that split the stream into those packets. Basically you will have a big buffer that you read your data into, and whenever you have a complete packet in your buffer, you memcpy it out and use it. But keep in mind, that the buffer might already contain the start of the next packet.
Members - Reputation: 119
Posted 21 April 2013 - 06:18 AM
Moderators - Reputation: 8353
Posted 22 April 2013 - 11:07 AM
There *may* be a bug in SDL, but I doubt it.
the missing data does not appear in the previous data received by SDLnet_TCP_Recv
Also: If you don't want your game to pause while dragging the window, install a WM_TIMER that runs the game loop while this is happening, or run the game loop from within WM_PAINT and keep re-invalidating the window.
Members - Reputation: 740
Posted 22 April 2013 - 09:18 PM
The concept of a stream means that even though you may send your data with 1 call to 'send' you may require multiple 'recv' calls to get that data. Your issue sounds eerily familiar to some of my younger coworkers issues when moving an application from udp to tcp. They would make 1 call to 'recv' per iteration of the application loop assuming (incorrectly) that send/recv was a 1:1 operation. Locally on their work stations this worked fine until they started sending larger amounts of data per send call. Over a WAN connection the issue was even more apparent.
As Ohforf sake mentioned you will need to figure out some sort of protocol to let you know when you have received an entire "packet" or "message". Many older text based MUDs just used the newline as a delimiter for sending information to the server. More complex protocols will use a fixed sized header to define the size and type of payload to expect. Others (like HTML) will use a combination of delimiter patterns and headers to send/receive different payloads. I personally like to point beginners to the SFML sf::TcpSocket and sf::Packet implementations that handle this pretty simply and straight forward. I am not saying this is a great implementation (though many do much worse) but it is simple enough to get the point across.