ZenVirZan":2xo2oaf9 said:
I already knew TCP was bad for games - Considering I've been busying myself with all of the extra little details, I figured I'd swap later, and I guess this time is now. I'll keep my TCP connections for the server listings and stuff that doesn't require low latency, and move all of the in-battle messages to UDP.
Due to the nature of UDP and its lack of streaming, how do I differentiate between two connections coming from the same IP address? I'm not sure how UDP works. If I bind a UDPSocket and listen to it, how do I send back the appropriate information? With TCP, you just #print back on the returned stream, but you can't do that with UDP from what I can tell.
EDIT: I am already using a thread with a network loop of blocking #gets and it seems to have a delay of about half a second. Would that be due to inefficient thread usage or is that just TCP? The game sends instantly, and the server receives and replies instantly too.
That half a second delay sounds very much like the OS socket buffer I described, check to see if you can do setsockopt for your network socket.
And with two connections from the same address, you can do what TCP does, TCP has a listen server and a client connector, the client can choose to bind to a port or pick a random port (Picking a random port is the best option for this to work), but the listen is on a fixed port. Because the same IP address can't communicate from the same port anyway, the port can be used to identify two different connections.
Here's an example:
Server is listening on port 27000
Client A starts on random port, it is given port AAAAA
Client B starts on random port, it is given port BBBBB
In TCP, both clients will connect to the server, the server will go "Oh, AAAAA has connected, I'll now send directly to AAAAA"
With UDP, you can say "I just received a packet from IP:AAAAA, I will store that information and send my reply to IP:AAAAA"
This solution doesn't even break down with network address translation (NAT), because the routers will map a port in the sense of X:Y you can guarantee that when the client sends on X, the server will receive on Y and when the server replies on Y the client will receive on X. (This problem is totally resolved with IPv6).
In my XI Networking Engine, I had it so the server will tell the client what port they are free to communicate through to simplify and obscure the client identification method, this is what a lot of games currently do (The ones that ask you to forward a range of ports when you want to run a server).
So the Client A would communicate to the server on the server's public port 27000, the server will then reply to Client A saying "Okay, I have opened port 27001 for you, please use that port so I know who you are" and then Client A will send it's packets to that port instead. That method moves the client identification method onto a socket level rather than a port level so you no longer have the risk of NAT routers bugging out (Which they sometimes do).