SDL_net TCP packets getting truncated

Started by
4 comments, last by evillive2 11 years ago

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.

I currently send data by using SDLNet_TCP_Send(socket, packetBuffer, messageLength) and receive them by using SDLNet_TCP_Recv(socket, packetBuffer, bufferSize)
Does anyone know if there is a solution to this problem or if there are any good workarounds?
Advertisement

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.

I understand that TCP is a stream protocol, but when the data received is split, the missing data does not appear in the previous data received by SDLnet_TCP_Recv - all of the data received while the window is paused are all missing the first few bytes of data.
Post your code, sending and receiving.

the missing data does not appear in the previous data received by SDLnet_TCP_Recv

There *may* be a bug in SDL, but I doubt it.

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.
enum Bool { True, False, FileNotFound };

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.

Evillive2

This topic is closed to new replies.

Advertisement