Advertisement

sockets/c++/real time game/accept()

Started by March 28, 2004 03:36 PM
13 comments, last by Dunge 20 years, 9 months ago
Ok.. I want to make one of my OpenGL game playable over internet (or LAN). I looked a bit over win32 sockets and understand I need to do (exemple for the server): WSAStartup socket bind listen accept send/recv while the game is playing close WSACleanup but the problem I get is that for the accept and recv function, every code I read use infinite loop until someone actually connect or send data... this is ok for dos but I don''t want my opengl game to stop until someone connect, I want them to connect anytime in the game.. someone told me to look at threads but it seem a bit complicated for nothing, I guess there is another way??! thx for the help!
First: if your game is real-time, TCP sockets are not going to treat you well. You need UDP for real-time games.

Second: if you want to accept() without blocking, you can select() on that socket, and it''ll come back as readable if there''s anyone waiting on it. Then call accept() to return the connected socket.

But use UDP. Or a network abstraction layer. (HawkNL, perhaps?)
enum Bool { True, False, FileNotFound };
Advertisement
Ok,.. here the update.
I used this tutorial : http://www.gamedev.net/reference/articles/article1297.asp
it's pretty good, exactly what I want, receive the connection attemp/data/close/etc in windows messages so it's great.

The problem is that he use TCP (stream)... and I tried with that the bind and listen (server) and connect (client) return 0 (no error) but the server didn't get any FD_ACCEPT message.

switching to UDP like you said is faster, I found out that we don't nee listen since it always listen. Well automaticly when the server start it receive an FD_WRITE message (wtf?).. the client when using connect it return 0 (no error) and when using send() it return the number of byte so it should be ok but again, the server don't receive any FD_READ messages

[edited by - Dunge on March 29, 2004 12:18:53 AM]
Im wondering why UDP is better? Can you explain why and not just say its better
UDP is is a very simple low level protocol; it simply sends a fixed size packet via a known route to the other end. There''s no reliability inbuilt; the protocol does not send a packet in reply saying "I got that one". It is also not sequenced, which means packets could arrive out of order.

TCP is a sequenced, stream based (bytes, not packet), reliable protocol all of which requires the protocol to only deliver information to the application when it knows it has the right piece of information. However, TCP works fairly well in good conditions; if there''s no packet loss then you get the packets in a timely fashion. However loose just one packet (which is not as rare as you might think) and TCP has to organise the other end to retransmit; this will loose you at least one round trip. In the meantime, nothing else gets through; since the data has to arrive in sequence. This means TCP would stall your data on any packet loss.

This would be a problem for first person shooters, or other fast paced games where you want bulk transfer of time critial data (ie. player positions that move rapidly). So, it really depends on what the data is for; for example TCP is very good for http, ftp, and other bulk transfer of data where it''s important to get it all, in the right order, but time is not as important. UDP is good if you want it now, but any delays means the data is worthless - consider the position of a fast moving plane.

Most games still use UDP, because you can implement your own relability, retransmission and ordering qualities on top of the protocol for maximum control. Writing a fully fledged version of TCP is not what you want; a good place to start is simply adding a sequence number (each packet is numbered incrementally) so you can spot missing or out of order packets and handle them appropriately.

In summary; TCP great, UDP great. But for most game data (except Chess) you probably want UDP. You might want to use TCP for bulk transfer of content or for accounting purposes however.

Hope that helps...

Viper
Thanks, but could you explain how it works like in starcraft?
every udp packade is sent to the server, who puts them together in a new one and sends it to all the players?
Advertisement
I believe starcratf, like most other strategy games, use Star-type architecture. Basically, when a client needs to send something, it will send it to ALL players (or appropriate team players, if there are teams...) That way, if the host Disconnects, the others can still continue playing, wich is not the case with games like FPSes or MMORPGs, where the client sends everything to a single server, and the server sends to every client, and there are no packages sent between clients...
That''s not a "star" topology; if everyone sends to everyone, then it''s a "fully connected" topology.

A "star" topology is when everyone sends to one node (the "server" "hosting" the game) and then that node echoes back to all the nodes. That will, of course, fail, if the centerpoint of the star (the machine hosting the game) fails, the game fails.

If you want to be more resilient, then all players need to have the address of at least one other machine to use as the back-up host, and use that when the main host fails. (You can of course go deeper into this kind of design)
enum Bool { True, False, FileNotFound };
Hi, I''ve got a question. I''m using UDP, and in my serverthread I wait for packets that arrive from a client. I have to know the client socket from which the packet was sent. With UDP, do I have to listen on a port? I thought I just use accept() and that will give me the address of the socket. Is this right?
To use UDP:

s = socket( ... IPPROTO_UDP ... )inaddr.sin_addr = INETADDR_ANY;inaddr.sin_port = htons( MY_PORT );bind( s, ... &inaddr ... )while( 1 ) {  recvfrom( s, ..., &oneOfMany );  deal_with_message_from( &oneOfMany, ... );} 


There are no connections in UDP, thus there is no "accept()," only "bind()" and recvfrom/sendto.
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement