Any RTS server datagram reliability comments, TCP / UDP ?

Hi
In previous questions, I have determined that the best way to do my Java RTS is with UDP.
Some insisted UDP only.

What sort of packet verification strategies are best, needed? UDP is release and forget.
Will my server have to communicate with any clients that haven't sent in a packet for a frame of the game? Should the client send each packet twice?
How do Blizz and Microsoft do it in Starcraft and AoE ?

I've only done testing on home LAN, university LAN, where UDP is pretty reliable, but dare I try it on cross-town connections yet? UDP packets need extra coding for reliability - like?

I'd prefer to start off correctly with my client-server.
I am good with datagrams and TCP/IP.
LVL 1
beavoidAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

dpearsonCommented:
My advice would be to use a combination of UDP and TCP.  E.g. Send UDP for rapid updates, but follow up with a TCP packet every few seconds to synchronize everything.  That way you know that every <n> seconds you are getting a full state exchange between client and server.

The whole reason to use UDP is because you know that if a packet is not delivered, you don't want to retry that packet.  E.g. If I send you an update every time my character moves to a new position in a game, old updates are irrelevant and should NOT be resent - since all I need is the most recent position.  I can just keep sending the new position (with either every move or say every second) and you may lose some of them, but that's OK (since I just need the most recent).

Writing your own retry and resend logic for UDP is a lot of work and hard to get right.  You almost certainly will be better off just adding in some TCP packets (which bring all that for free with correct and highly optimized code).

Doug
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
beavoidAuthor Commented:
Thanks
Are you suggesting every 3rd or 5th or 8th
packet be TCP?

When a client attempts to join the game, should I send a TCP reliable message?
So, a server must have a TCP and UDP socket? Clients also?
With the client object and server having a TCP and UDP connection available,
 is there overlap to worry about? I mean, do they conflict?
Thanks
0
dpearsonCommented:
>> Are you suggesting every 3rd or 5th or 8th packet be TCP?
I would do it separately - based on time not number of packets.  E.g. Sync on TCP every 2 seconds.  You send UDP whenever you have new state information, e.g. after any unit moves.

>> When a client attempts to join the game, should I send a TCP reliable message?
Yes

>> So, a server must have a TCP and UDP socket? Clients also?
Yes

>> With the client object and server having a TCP and UDP connection available, is there overlap to worry about? I mean, do they conflict?

No this should not be a problem.  Just attach a timestamp to each message when it is sent and use the most recent values you have received.  If the UDPs get through, then you will be using them.  But if the connection is very poor, you'll automatically fall back to the slower TCP packets (because you won't have any newer UDP packets).

Doug
0
Learn Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

beavoidAuthor Commented:
I'm trying a framework below, where the clients connect with TCP before any UDP begins. But, the ServerSocket object never gets bound. It crashes, and I can't see why.?

Any comments?

Thanks

import java.net.*;


public class DRWserver extends Thread {
	
	public int numClients, numClientsExpected;
	
	
	public static int TCPport=88;
	
	
	ServerSocket serverSocket;

	public DRWserver( int playerCount) {
		
		numClientsExpected=playerCount;
		numClients=0;
		
		start();
		
	}
	
	public void run()  {
		
		try {
		System.out.println("Creating TCP socket on port "+TCPport);

		serverSocket = new ServerSocket(TCPport);
		boolean AcceptingClients=true;

		
		while (!serverSocket.isBound()) {
			System.out.print("x ");
		}
		
		while (AcceptingClients) {


			System.out.println("\nClient accept()");
			Socket socket = serverSocket.accept();

			System.out.println("Client join?");
			System.exit(0);
		}
		
		
		
		
		} catch (Exception e) {

			System.out.println("\nDRWserver run ex : "+e);
			e.printStackTrace();
		}
		}
	
	public static void main(String[] args) {

		
		new DRWserver(3);
		
		

	}

}

Open in new window

0
beavoidAuthor Commented:
Could it be an OS thing? I doubt it.
0
dpearsonCommented:
Different question than the original.  I think you should post a new one.
0
beavoidAuthor Commented:
I have posted a new one, thanks

but just to confirm

This is still
Game State on the server.
?

That is getting to me! Because the UDP packets seem to get muddled! But, if I use a TCP message to straighten the game state out, and UDP for unit deltas, that should work?
Should the client ask for a TCP update, or the server automatically send a full update every 900 game cycles/frames?

Thanks
0
dpearsonCommented:
Yes game state should always live on the server - that's for security (server code runs on a computer you control, client code runs on a computer you don't control - so it can *always* be hacked).

But, if I use a TCP message to straighten the game state out, and UDP for unit deltas, that should work?
Yes that should be fine.

Should the client ask for a TCP update, or the server automatically send a full update every 900 game cycles/frames?
You can do this either way, it doesn't really matter whether the server always posts the update or the client requests the latest state.

Doug
0
beavoidAuthor Commented:
Okay, thanks,

I am getting much closer,

but do you think an ObjectOutputStream or a DataOutputStream makes more sense?

ObjectOutput stream is so well contained, and saves the time of extracting exactly what you want from the stream?

I'm thinking datas members like this struct on the TCP side, integers and bytes as needed by various messages, where the UDP will have its own way of sending the message.
{
    int messageType;
    int i1, i2, i3, i4;
    byte b1,b2,b3,b4;
    int[] I1, I2, I3;
    byte[] B1, B2, B3;
}

? thx
0
beavoidAuthor Commented:
My TCP code on my client isn't linking with my TCP code on my server.

It's probably a simple thing. Do you mind if I post it here?
0
beavoidAuthor Commented:
thx
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Game Programming

From novice to tech pro — start learning today.