🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

UDP Theory

Started by
34 comments, last by MadProgrammer 22 years, 6 months ago
i''m writing the networking part of my game, its all i need before its alpha time! YIPPEEE!! I would like to use UDP for the network protocol because its fast. I am expecting for there to (eventually) be about 10-75 people connected to the server (well, not really ''connected'' because UDP is connectionless, but...). Well, on the server, do i just have 1 UDP socket that accepts all incoming traffic? If so, i just go thru my vector (or linked list) of clients, check to see if the SOCKADDR i have stored for them is the same as the 1 that i just got in recvfrom(). If it is, we do stuff. Problems: finding out what client just send what i got in recvfrom() sounds like it would be costly processor-wise. that would be O(numCliens) every time a client sends something. I plan on using liked lists cuz people are gonna be signing off and on all the time. Should i consider using regular arrays so i can do faster searching algorithms? My game is supposed to be an online 3rd person shooter. can i do a sendto(mySocket, ....) while i''m doing a recvfrom(mySocket,.....)? Hmmmmmmm. if not, i could make a dedicated socket for just sending stuff to the clients. Would that work? Having two sockets, mySocketIncoming that i''m just sitting in a recvfrom() on and antoher socket mySocketOutgoing for sending positional updates and the like to the players. please help me figger this one out. networking is arguably the hardest thing i''ve done so far in my game (and the longest to debug) <the> MadProgrammer
Advertisement
MadProgrammer

I don''t want to write your code for you, so here is some food for thought. Why search at all?

If you don''t get it I''m still willing to help...
i still need to search because the packet i got prolly represents and update in the client''s x/y coords, therefore i hafta update those in the struct that represents that socket (and the client behind that socket) so that the next time i broadcast out all the latest x''s/y''s, the one that client just sent the server is the one that is sent out

i guess i could just send out his new coords right then and there, but i dont know if that would be a good idea.... i guess it would work.... hmmmm.... please go into more detail on your idea.....

p.s. I''m not asking for code, just theory
Lets look at the problem in a different way.

I''ll be the server and you''re going to be the client, ok.

Think of the incoming packets as little programs that the server or client must execute, basically byte code.

Syntax: "player#, command, player#"

MadProgrammer says to Burp: "0,hello"

Burp says to MadProgrammer: "1,hello"

SomeOtherDude says to Burp: "0,hello"

Burp says to SomeOtherDude: "2,hello"

Burp says to MadProgrammer: "1,include,2"

Burp says to SomeOtherDude: "2,include,1"

MadProgrammer says to Burp: "0,move,1"

Burp says to SomeOtherDude: "2,move,1"

SomeOtherDude says to Burp: "0,jump,2"

Burp says to MadProgrammer: "1,jump,2"

SomeOtherDude says to Burp: "0,quit,2"

Burp says to MadProgrammer: "1,quit,2"

So the server knows the client from the number it sent, which in turn the client got from the server. When SomeOtherDude says to burp "0,quit,2", that tells the server that 2 wants to quit. The server knows that client 2 is SomeOtherDude.

This is not the fastest way, its just an example!

If you don''t see why you wouldn''t have to search, I''ll give you another clue...


Ok,

Lets try and break out of this riddle. MadProgrammer and burp are both correct on this one. If fact this is a situation where there are many correct answers (like many things in life) and the quality/speed of the correct answer depends on the solution chosen.

The key here is to ensure that the data that is sent to the server has sufficient information associated with it in order to identify the client that sent the data - a simple number as burp suggests. If that is the case then there shouldn''t be any need to grab the incomming IP data to find out where the packet came from - thus no searching.

The down side to this is that there needs to be identification info sent with the packet but in this case this will be a very minor overhead and probably far outweigh the processing needed to seach through a table of IP addresses to identify the client.

henry
HenryLecturer in Computer Games TechnologyUniversity of Abertay DundeeScotlandUK
Forgot to answer the other part of your original question:

"can i do a sendto(mySocket, ....) while i''m doing a recvfrom(mySocket,.....)? Hmmmmmmm. "

The answer is yes but the result and how you actually do it will depent on the nature of the socket.

If it is a default synchronous-blocking socket then you must wait for one send or recv to be completed befor the next can be done - the program will be held up in the send/recv call.

If it is a synchronous-nonblocking socket then you will need to use select() or ioctlsocket() to poll the socket to see if data is available.

If it is a asynchronous-nonblocking socket then the notification of incomming data will be posted through the windows message handler.

henry
HenryLecturer in Computer Games TechnologyUniversity of Abertay DundeeScotlandUK
henryx

A programmer who doesn''t like riddles, that doesn''t compute

Any ideas MadProgrammer...
When you are programming servers with sockets, it''s better to create one socket in the server to let the clients make the connect. When the client have made the connect, the server will create a new process that create a new socket only for that client. If you have 5 clients connected, you must have 5 sockets of data, one per client, and one socket for accept the connections of more clients.



"If you''''re gonna die, die with your boots on"
"If you''re gonna die, die with your boots on"
quote: Original post by Gelmir
When you are programming servers with sockets, it''s better to create one socket in the server to let the clients make the connect. When the client have made the connect, the server will create a new process that create a new socket only for that client. If you have 5 clients connected, you must have 5 sockets of data, one per client, and one socket for accept the connections of more clients.


That''s OK, as long as you''re only expecting no more than 10 or 20 clients at once, but if you''re expecting 75 odd clients at once, then this is very inefficient. 75 sockets and 75 threads is a big waste of system resources, plus think of all the context switching the CPU would be doing!

You''re better off using 1 socket and something like two threads (so one can be CPU bound, and the other I/O bound - that is, one is processing a packet while the other waits for the next one.)

There''s a number of ways of doing this, my personal favorite is using I/O completion ports (look them up in MSDN, the pop3 sample that comes with the networking part of the platform SDK is good as well), since they are extremely fast, and mind-boggingly scaleable. I doubt you''ll find a faster/more scalable solution for the windows platform.

Another method may be using select(). This isn''t too bad, but if you''re looking for portability, then you can''t select() on more than 64 sockets at a time. Mind you, I don''t believe portability should be a goal when you''re writing a high-performance server. It''s good on the client, but you generally only run a few servers anyway.

Anyway, that''s just my two cents. Good luck!

codeka.com - Just click it.
first, i''m using UDP so only 1 (or 2 maybe, see earlier post) socket(s). There is no connecting, i just ditched that part of my TCP code.

so now i''m looking at a couple options:
1st, i can send each user an Id that is their index in the array of clients on the server. Problems:
-> Clients hafta be stored as vector on server, thats bad for adding/deleting clients.
-> also, if clients[2] dies, then i kill it and hafta tell clients[2]..clients[n] to decrease what they think is their index on the server

other option: use a linked list. instead of using a short for the indexing above, send an int (2 more bytes) that is the memory address of the node in the linked list that the represents the client associated w/ the packet sent. Problems:
-> A little more difficult to implement (more pointers)
-> 2 more bytes / packet (thats not too bad)

ne comments?

This topic is closed to new replies.

Advertisement