• Popular Now

• 12
• 27
• 9
• 9
• 20

This topic is 3582 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I'm making a program where I receive packets with SDL_net in the game loop. For some reason, every time I call the function SDLNet_TCP_Recv(socket, buffer, 512) in the game loop, the program freezes. The code:
void Player::move(bool p) {
if (SDLNet_TCP_Recv(socket, buffer, 10) > 0) {
std::cout << buffer << std::endl;
memset(buffer,0,sizeof(buffer));
}
}


Where I invoke the move method inside the game loop, like this:
            for (std::list<Player>::iterator it=players.begin(); it!=players.end(); ++it)
it->move(gameball.get_paused());


If I remove the SDLNet_TCP_Recv() line, it works..

Share on other sites
It blocks because it waits for data to arrive, recv is supposed to do that. Using a blocking call in the game loop is a terribly bad idea, as it adds freezes that are unpredictable and can take several seconds.

At the very least, if you're not able to offload the network stuff to another thread, you should use select/poll (I think SDL calls the respective function SDLNet_SocketReady) before attempting to read from the socket. This isn't perfect as it still stalls the game loop, but not nearly as bad.

Alternatively, you could set the socket to non-blocking, in this case you will get an error code instead of blocking. However, that isn't so good either, as it burns CPU cycles for nothing.

Lastly, you could create a separate thread for network which you can have block until something arrives, and then read the data while the game loop isn't interrupted. While no data arrives, the thread is blocked, so it doesn't eat CPU time. Ideally, you would make it block on select/poll rather than recv, since then you can also specify a timeout and watch more than only one connection at the same cost. This also allows graceful thread termination (as opposed to killing a thread blocked in recv) when your application exits.