NIO tcp pinging

Hello.
So I’ve got basic networking in my game working… (connecting, sending sending data …). Now it’s come time to synchronize client and server and first thing I need is determine ping between them. For simplicity, I assumed latency spike won’t occur and go ahead using TCP, not to mess with UDP and routers.

This is how I did it (obviusly I’m not satisfied):
When server authenticates the client (password if any is ok) then client starts a new thread that puts current time in a message and sends it (9 bytes, 1 byte ping_request header and 8 bytes long for nanoTime() ). Server upon receiving sends them back right away with ping_response header. Client reads value from message and substracts from nanoTime() so it gets ping time. I do that 5 times in 100ms interval.

Problems with this are that some messages get lost on the way to server, but this isn’t really so strange as I don’t deal with merged packets (yet) and I just use channel.write() without registring write on selector (again, yet).

Most of the times ping is correct on LAN, like 3 ms, but first time it’s ~30ms and sometimes when doing more pinging (like 20 times) I can get 150 or something like that. I’m interested is this sufficiant? Is new thread approach a way to go? Do I need stop all other net in/out and how often and how many times I need to do pinging to keep computers synchronized?

Here’s the thread code:


		public void run() {
			System.out.println("HP: Starting ping procedure.");
			// Kova: sends 9 byte ping packet TIMES_TO_PING times in PING_INTERVAL ms interval
			for(int i=0; i<TIMES_TO_PING; i++) {
				System.out.println("HP: pinging for " + i + " time.");
				write_buffer.clear();
				write_buffer.put(PING_REQUEST);
				write_buffer.putLong(System.nanoTime());
				write_buffer.flip();
				sendInstantMessage(write_buffer, sc);  // does channel.write()
				try {
					Thread.sleep(PING_INTERVAL);
				} catch (InterruptedException e) {
					System.out.println("HP: Error sleeping, thread interrupted.");
					e.printStackTrace();
				}
			}
			System.out.println("HP: Ping procedure finished.");
		} // end: thread, run()

I wrote a quick ping utility in JGN using nanoTime and I consistently get about 3000 nanoseconds (0.003 milliseconds) replies. That’s both running on my local machine, but that should give you some idea. My code is also doing a whole lot more with message conversions and such as well. Your 3 milliseconds may be due to the crap that is System.currentTimeMillis() though.

I’ll take a look at your ping utility in JGN.
hmm…strange… in 95% of time ping is 3ms and I use nanoTime() also (not currentTimeMillis() that is known for it’s low resolution in windows). While pinging with windows ping utility which is also based on TCP i get <1ms except for first time. So java is 2-3ms slower?
Anyway back to the point… if anyone has an advice or suggestion about my ping impletation I’ll be happy to listen.

If you mean the "ping " command in a command prompt in windows, that doesn’t use tcp/ip. It sends a IMCP Echo Request, which has a LOT smaller payload than tcp/ip packet.

hmm… when I start that ping in Sygate firewall it shows “tcp/ip ping command” as application name…

To give some feedback on my progress… I’ve figured out that TCP combines packets more often then I though, It’s best that at the pinging time absolutly no other sending is done and that timeout between ping is good enough, like 250ms. I though that my small packet of every 1 sec won’t bother ping algoritham and that ping interval of 100ms would have time for packets to go freely without TCP combining them… but ping on LAN was ~50ms average and up to 100ms when (I guess) ping was sent near or at same time game packet was sent. When I increased ping interval to 250ms ping droped and it’s as it is supposed to be, ~1 ms, and sometimes ~30ms when (again I guess) ping is sent near or at same time game packet is sent.

So at the end I deceided I’ll give up on unnoticable synchronization with server and just put a message “synchronizing” for few secs after player joins the game. Only problem is pining in middle of play, where packets are sent very freaquently, every 100ms. I’m thinking when time for pining comes to send ping message first and then game message, so game message is the one with little extra lag. Other option is to send ping messages between game messages, but that would mean message would be sent every 50ms when that starts, and I think TCP would combine them or something. I really need to find what is maximum number of messages I can sent in a second without TCP spliting or combining them, anyone?