extreme ping with tcp over inet

Started by
9 comments, last by Dreddnafious Maelstrom 19 years, 6 months ago
Hi all, I've just made my network code working. I was just connected to my localhost so far. Everything was fine (Ping:0ms, what a surprise ;) Yesterday I sent it to a friend to check it out over internet. And, gosh, I had a ping of over 500ms constantly... What the heck? I tried to figure out if anything was wrong with the ping calculation or something, but even without the ping-o-meter you could tell that it was laggy as hell. We both have a dsl connection and are living in the same city, so I think there MUST be a way to speed this up. I have pings of 40ms or so on unreal tournament btw. My game uses TCP over winsock for communication. Is this the reason, why it's so slow? Several articles stated that UDP could give you a big increase in speed. Is this the way to go? Thanks in advance for your replies.
Advertisement
If you're using TCP, the first thing to do is to turn on TCP_NODELAY. Else the TCP stack will not send your data immediately, but instead wait for some time (200 ms or so) before forwarding the data, hoping that you'll write something else that it can coalesce into the same packet.

However, if you ever get a dropped packet, TCP will not be your friend; it'll take a while to re-transmit the dropped packet, and meanwhile, the receiving program will not get the other (later) packets, because the TCP stack is still waiting on the earlier packets. If this becomes a problem for you (and it will, on the Internet) then you should go UDP.

Read the article in BookOfHook on Quake III networking, if you're doing an action game with few players, that strategy seems very valid.
enum Bool { True, False, FileNotFound };
Pinging with TCP, for the reasons already mentioned, is a very tricky affair. Even if you do eventually go with TCP for network communication (which I don't recommend), definitely use UDP or ICMP for timing.
You must be doing something funky in your network code. I'm in Scotland, UK, and I can ping a MUD server in Canada using TCP/IP (sending a string, and waiting till the reply message comes back), and I get ~200ms on a good day
How much data are you trying to send? send too much and you're bound to affect the ping...

Thanks for your replies guys!

I think the question was a bit misunderstood.
I don't have a problem with the ping reflecting my "real" delay.
My game is just to laggy over the net.

@hplus:
I haven't heard about this "TCP_NODELAY" Thingy. Will check it out later.

I actually read this article about Q3's networking model yesterday after writing the post. Very interesting, no need for reliable packets... seems pretty easy to implement.
Well, I haven't got the idea of delta packets, yet.
Do you simply stuff in everything that has changed since the last ACK? Is that the meaning of "delta" here?

@Sneftel:
Don't you think I should use my own networking layer for pinging? I mean, what sense does it make to use ICMP to ping when it gives me a value that is far away from my real packet delay. (To calculate client prediction, etc.)

@SpaceDude:
I'm not sending very much data yet. (I think so at least O_o)
The server sends the gamestate to the clients 10 times a second.
Which is only about 100~200 bytes at the moment. (Will probably increase in the future, this is just for testing :)
Whats your ping (using DOS ping command) between you and your friend?

Also, just cause you only send 100 bytes doesnt mean your're not gonna have a high ping. Bandwith is different from latency. Even sending 1 byte a second you can have a large ping time.

As the others stated above, look into the TCP_NODELAY thing, as not having it on will cause packets to be queued until either a size or time threshold is reached before actually sending the data.

-=[ Megahertz ]=-

[Edited by - hplus0603 on September 16, 2004 6:44:30 PM]
-=[Megahertz]=-
My concern was that you where attempting to send something like 100 kb/sec... which clearly isn't going to work on a DSL connection... but between 1 and 2 kb/sec should be fine
I actualy have the same problem, when i use my network code to calculate a ping on my local system i get expected times like 0.7ms, but as soon as i'm using my pingutility to ping another computer (even on a lan and people of which i know i have a 30ms ping to) i get pingtimes of ~400ms.

I used setsockopt to set the TCP_NODELAY option to off, as was suggested but that only seemed to have shaven off 100 or so ms, i still get 300ms pingtimes to people i know i should get 30ms pingtimes from.

Is this just the physical barrier of the TCP protocol or are there other options i need to switch to get decent pingtimes? i'm sending a mere 32bytes random data packet.

I dont think i want to use UDP i just want a regular pingtime with the protocol i'm using now, that is winsock and tcp.
The trick to making TCP run smoothly is treating it like the streaming protocol that it is.

a) buffer all outgoing messages and only send the buffered data once per interation of your main loop. This cuts down immensly on overhead.

b) Your main loop should be running hundreds if not thousands of iterations per second even if you are rendering graphics at a lower FPS. Do not force a frame render every iteration. Allow for frames to be dropped and maybe even cap the rendered frame rate to free up time to handle network data. You cannot avoid software induced lag, you can only try to minimize it.

c) buffer all incomming messages and break them apart in software when you're actually looking to handle the individual messages. do not try to break apart messages as the data comes in. It's a big giant waste of time.

see

http://www.icarusindie.com/DoItYourSelf/LifeOnLine/

The client contains these concepts implemented in a plug and play winsock class. You just need to supply the server end of it using the same concepts.

TCP can be very fast. You just have to implement it properly to reduce network lag and write tight efficient code to minimize software induced lag.

This topic is closed to new replies.

Advertisement