I'm now planning to develop a real-time mmo in the future using udp as the transmission protocol since it has lesser overheads than tcp... I understand that between the client and the server, they have to do 2 basic things, the client needs to send server updates such as character positions..movements..hitting a monster..etc, and the server needs to update all the clients connected to render the changes on their screen...

For the client updating the server, I'll most probably do it by sending fast UDP packets to the server, but however for the server to update client, the server will send UDP packets to client containing the updates, however what if a client is behind a NAT? How do the server "push" udp packets to clients connected to a NAT-based network?

I plan to write the server in Java, I've also read about NAT hole-punching with various techniques like STUN..TURN..ICE.. however I can't seem to find a good framework/solution for it..

I also wonder how MMOs today like Maple Story..WOW..League of Legends implemented it..

  • 2
    \$\begingroup\$ Is this question any different than gamedev.stackexchange.com/questions/681/… \$\endgroup\$ – Tetrad Feb 28 '12 at 18:19
  • \$\begingroup\$ @Tetrad: Doesn't seem to be. \$\endgroup\$ – Nic Foster Feb 28 '12 at 18:58
  • 2
    \$\begingroup\$ The other question had two parts to its question; peer-to-peer and client-server. But all its answers were only applicable to peer-to-peer, while this question is solely about client-server. \$\endgroup\$ – Trevor Powell Feb 28 '12 at 20:20
  • \$\begingroup\$ This is a bit off topic, but is good advice. First rule of making online games: never trust the client. The only thing that the client sends to the server are keypresses. \$\endgroup\$ – jcora Feb 29 '12 at 11:54
  • 2
    \$\begingroup\$ Second rule of making online games: if all you ever send are keypresses then you end up duplicating input handling on 2 processes, as well as needing yet another protocol for any non-player clients. Better to convert keypresses to semantically meaningful events before you send them. \$\endgroup\$ – Kylotan Feb 29 '12 at 20:09

A static MMO server (that is, one which is not located behind a NAT device itself) can simply send packets to users who are behind a NAT device exactly the same way that (for example) web sites send packets to them -- just ignore the possibility of a NAT device and send replies to the IP+port that's visible on incoming packets from the users; NAT devices rewrite packets that pass through them so that two-way communication with servers is possible that way.

As an MMO server (like any other kind of publicly available internet server), you don't have to think about NAT at all.

| improve this answer | |

There's no guarantee that a firewall (whether NATing or not) will let UDP packets through at all, so your client and server should be prepared to communicate over TCP if necessary. Typically, the client will create a TCP connection to the server, and thereafter both will talk back and forth over that connection.

For setups where no direct connections are permitted through the firewall, you may want to also support tunneling the TCP connection through a SOCKS proxy. In particular, it may be a good idea to query the system default proxy settings and use them if a direct connection fails.

It's perfectly feasible to use the same message format for both UDP and TCP. There are some features that you'll only need for one protocol or the other; you can either have two variants of your message format, one for each protocol, or just include all the necessary features in both:

  • UDP includes the packet length in the header; with TCP, you need to have some way to tell where one message ends and the next begins. (Of course, this may be useful with UDP too, if you want to be able to pack multiple messages into one packet.)

  • TCP guarantees sequential transmission; UDP packets may be lost or arrive out of order, so you need sequence numbers of some kind (and probably some retransmission mechanism). Of course, TCP connections may break for various reasons, in which case knowing where to restart after reconnection can be useful.

To minimize the additional latency when communicating over TCP, it may be useful to disable Nagle's algorithm using the TCP_NODELAY flag. Instead, you may want to implement your own transmission buffering, collecting several small messages into one packet whenever possible (which is a good idea with UDP too).

Edit: Rewrote the second paragraph per comments below.

| improve this answer | |
  • 3
    \$\begingroup\$ I don't recommend ever trying to bypass firewalls by any means, including by trying to mask your network traffic to look like a different, approved type of traffic (web traffic going via an http proxy, etc). Firewalls are put there intentionally to restrict the flow of particular types of network traffic. Going out of your way to try to crack through a firewall is a good way to get yourself classified as a threat/malware, and to make IT managers hate you. Please, please don't do this. \$\endgroup\$ – Trevor Powell Feb 29 '12 at 11:41
  • 1
    \$\begingroup\$ @Trevor: I do agree that "trying to mask your network traffic" is generally a bad idea (or at least a decision that should be left to the user). However, SOCKS proxies are meant for tunneling TCP connections; there's nothing deceptive in using them for their intended purpose. Using HTTP CONNECT may be slightly more questionable: in principle, there's no difference between it and SOCKS, but some network admins might not realize that it can be used for more than HTTPS, and may not have secured it as intended. Still, if the system config says "use this proxy", why not at least give it a try? \$\endgroup\$ – Ilmari Karonen Feb 29 '12 at 12:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.