0

I am writing a simple C game that accepts key inputs over the network. As it is my first time handling sockets in C, I am facing some problems with some functions. This function called 'recv', seems to wait for any network messages in the TCP connection until data is received. The problem is that since this 'freezes' the program while there are no messages, my normal game code that is supposed to run in an infinite loop won't work properly. Is there a way I could wait for network messages AND run the game at the same time?

while (1) //Infinite 'game loop' start
    {
    read_size = recv(newsockfd , client_message , 2000 , 0);
    if(read_size > 0)
         {
         //Do something
         }
    //Game code here (Doesn't work when there are no incoming messages!)
    }
Joshua Jang
  • 107
  • 2
  • 10
  • 5
    Make the socket non-blocking? Use polling with zero timeout? Threads? – Some programmer dude Jul 13 '17 at 07:20
  • 2
    You could use [select](http://man7.org/linux/man-pages/man2/select.2.html) (with timeout) to put your task in sleep. Obviously you should use a multi-treading approach – LPs Jul 13 '17 at 07:21
  • Take a look at: [using-select-for-non-blocking-sockets](https://stackoverflow.com/questions/6715736/using-select-for-non-blocking-sockets) – LPs Jul 13 '17 at 07:24
  • It depends on your game. If you have heavy work to do independent from user input, you probably need either a thread or [set the socket to non-blocking](https://stackoverflow.com/a/1549344/2371524) and check it periodically in your main loop. –  Jul 13 '17 at 07:24
  • 1
    If the game doesn't do much (e.g. just some update steps triggered by a timer), you can instead, as already commented, use `select()` with a timeout in your main loop. –  Jul 13 '17 at 07:25
  • Did some research on non-blocking sockets and used . It indeed works! – Joshua Jang Jul 13 '17 at 07:48
  • 1
    I think, the cleanest solution for rather simple (most) cases is polling with poll/select. non-blocking sockets usually are a sign of bad design and multithreading might be overkill. – Ctx Jul 13 '17 at 08:01
  • 1
    ^^ what @Ctx says. While an extra thread to wait for input would surely work, any input would be required by the 'game loop' in the other thread, and so the loop would end up 'polling' the thread output queue/whatever anyway. may as well just poll/epoll/select for it. – Martin James Jul 13 '17 at 08:18
  • my suggestion is either making the socket 'non-blocking' or better, use `select()` with a timeout – user3629249 Jul 14 '17 at 01:26

2 Answers2

2

The answer depends to an extent on what the background processing has to do and how frequently it has to run. If your background processing is a continuous task that needs to be running all the time and has no natural break, you probably need a thread. If it is simply something finite that must happen on a regular basis, you don't need a thread, you need poll or select.

poll is more flexible but select has an easier API but they more or less do the same thing. You supply a set of file descriptors, the events you are interested in and a timeout.

If you were using select in your case, you'd put your socket in the set of read file descriptors and supply a suitable time. When select returns, either your socket will have some data on it or the time out will have expired.

The advantage of using select over non blocking IO is that you can easily handle multiple sockets and instead of spinning in a tight loop when there is nothing happening, your process is suspended.

JeremyP
  • 84,577
  • 15
  • 123
  • 161
-1

Use multithreading to solve this issue. recv function is blocking therefore you cannot use single thread for this operation.

Or use non-blocking sockets (no timeout).

unalignedmemoryaccess
  • 7,246
  • 2
  • 25
  • 40