Search code examples
c#pingmultiplayer

Ping firewall protected computer (the multiplayer game way)


I'm writing a game server and I can't seems to find how to ping a clients computer (in the case they are protected by a firewall) in c#.

Can't seem to find any info on how game are doing it either. I have a tcp socket open with my client computer but I have not idea how to get the RTT to that computer from the server.

Any ideas on how to achieve this?


Solution

  • Given only a single guaranteed path of communications (the existing TCP connection in your case), your best option is probably to introduce a ping command into your network communication protocol. The client-side network protocol code should react to this command in the shortest possible time to avoid introducing delays that are more to do with the capabilities of the computer than the network latency, but this isn't too critical because a slow computer will necessarily have slower game performance and thus higher effective latency.

    The idea then is for the server to send a ping command with a timestamp value, and for the client side to simply repeat that value back to the server. At the server's end the timestamp is received and the round-trip time calculated.

    Depending on how accurate you're trying to be, the timestamp might only need to be a couple of bytes. Assume that you're only going to get accuracy down to the tens of milliseconds, and lots of variance depending on the loading of the network. With the right offset calculation you can get better than 1 minute worth of range at millisecond resolution into a 2-byte timestamp... good enough for most games.

    Or you can send a minimal ping command with no timestamp attached and track the timestamp at the server. In this case the server needs to keep a list of sent ping requests and process them in order as they return. You probably need at least a 1 byte identifier just to identify lost commands so you don't get out of sync, which makes this only very slightly more useful.

    Alternatively if your communications protocol includes a serial number on the transmitted command packets, have the client always return the serial number of the last command packet. You can keep a limited-length queue of serial numbers and timestamps on the server and calculate the ping time whenever the client sends you any information. This adds a few bytes overhead that might only really be useful for pings, but integrates the latency code into the base communications code, giving you a live latency figure without having to schedule pings.

    If you're doing command queuing in your network protocol to reduce TCP overheads, make sure that you have a method for pushing the ping command to the head of the queue.