Advertisement

to block or not to block........

Started by October 17, 2000 10:58 PM
7 comments, last by djsteffey 24 years, 1 month ago
I am writing a multi-player space shoot-em-up where you go around the "galaxy" (which isnt all that big) and shoot other players. Right now I have the connections set up as one person being the server/player and the rest connecting to him as client/players. after I connect, I set up the sockets to be non-blocking by calling the ioctlsocket(socket,FIONBIO,....); function. then I send packets every so often (like maybe 4 times / sec or something). But every time through my main loop i call the recvfrom(....); function. Now if there is no data waiting then it returns SOCKET_ERROR and I go about my business and dont bother trying to process data from the recvfrom call. But if there is data, then i process the data then go on about my business. Now my question is this: Is this going to cause a significant performance decrease versus using the method with WSAAsyncSelect(...); function and putting all that stuff in my main windows message handler ? One last thing......this is using UDP. "Now go away or I shall taunt you a second time" - Monty Python and the Holy Grail themGames Productions
Depending on what else your main loop does it could result in the server program taking up a lot of CPU time.

For example:

MainLoop()
{
if(PacketPresent)
ProcessPacket;
}

This would cause a massive drain on the cpu as your loop would be iterating too fast. On the other hand, if your main loop does a lot of "other" processing this would be no big deal.

I personally would recommend utilizing the Windows message handler. By using the message handler you would not waste any CPU cycles on "dry" runs.

If nothing else, just try out both methods and see which one works better. There really are just too many factors involved to get a definite answer.

webmaster@lostlogic.com

Advertisement
what about this.......
say i send my packets 4 times per second. Could i just check the recv function say every 250 milliseconds ? Or maybe I could even do it every 150 milliseconds, just to make sure ? That would throttle the loop from iterating too fast I would think. And if I check every say 150 millisconds, I feel pretty sure I would take care of all the packets as soon as they get there (assuming I send them all about 250 milliseconds apart.)
I realize with UDP, every packet may not make it. So I am sending X, Y and velocityX, velocityY so the individual computer can interpolate between packets.

"Now go away or I shall taunt you a second time"
- Monty Python and the Holy Grail
themGames Productions

What you''re talking about doing is called a polling method. It''s easier to program, but using windows events to notify an incoming message is significantly more efficent. If you want to read more about it then go get the book Winsock 2.0 by Lewis Napper. Read pages 69-70. It''ll give you a better understanding of why the polling method is not recommended.
In the setting you described, WSAAsyncSelect or WSAEventSelect would probably work better. Just keep in mind that there is some delay in processing a message through the message queue. Events would be a little faster, especially if you''re already using the message queue heavily. The message Queue would still be easier to use than events or polling.
I personally wouldn''t use asynch sockets with the windows message handler unless I were creating windows and using the message handler for other things as well. Asynch sockets aren''t the fastest way to deal with socket calls (as JonStelly has said), though they''re a natural for things like a windows-based telnet client. You''re probably better off going with overlapped sockets and WSAWaitForMultipleEvents perhaps with a timeout.
Advertisement
If you''re considering putting the recvfrom processing in a windows message handler, then you might as well create a second thread for network event handling and simply block on the socket descriptor. That way the thread is only active when there exists network data to be processed. Versus WSAAsyncSelect the data will tend to be processed with a lower latency. Versus WSAEventSelect this method would have a lower overhead. Of course the down side is that you''d have to use multiple threads, which carries it''s own set of headaches. However, WSAAsyncSelect would probably be preferable over polling once per pass of the main loop, as multiple packets could arrive during each pass, and calling recvfrom once could cause a bubble in the network processing.
I have found, whenever there is any alternative to polling, it is better.

Game tend to be written as one thread, from what I''ve read. But Async communications is best example of when to use a thread. You can send a special user message to the main thread''s msg pump when something important happens on the comm pipe. Otherwise, just have the comm thread update the pertinent data (need to use thread safe resources though).
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
But there''s no need to create a second thread for that. You can already get messages sent to the message queue without having to create a second thread.. WSAAsyncSelect will work.

If you want to create a second thread for receiving game data, you''d probably want to have that thread update the gamestate directly, and all your main thread would do is render your current gamestate and handle user input.

This topic is closed to new replies.

Advertisement