In this brief article we’re going to take a look at what really happens when we shut down a device’s wifi or unplug the ethernet cable off of a computer. While intuitively one would expect the current connections to go down, this is likely not the case.
We are going to see why this happens and clarify a few misconceptions that arise when testing disconnection scenarios in a multiplayer game.
» The disconnection mystery
One of the most popular issues when testing multiplayer games is trying out different disconnection scenarios and making sure that the client handles them correctly. In particular, with SmartFoxServer 2X, developers want to test reconnection cases using the HRC+ system, which reconnects clients that have lost connection for a brief moment.
In our HRC+ documentation we already provide directions for testing these cases, but we all knows reading the docs is boring 🙂 After all this seem very intuitive: unplugging the client’s network cable should immediately trigger a disconnection. (No network must equal to no connections, no?) But this isn’t the case. In fact, neither the operating system nor any application dependent on it (e.g. SmartFoxServer) will bat an eye if we unplug the cable or wifi.
So, what gives?
» A brief peek behind the curtains
To solve the mystery we need to take a quick look at what’s behind all this, in other words how the networking infrastructure works in most computers and devices, smartphones included.
Below is a simplified representation of the 7 layers of the OSI Model, which is an open and standardized model for telecommunications and is implemented in all major operating systems, from Android to Linux and Windows.
Without going into unnecessary details, this model describes how network communications work from the electrical impulses (layer 1) up to the application data (layer 7) and going through a series of transformations and encodings through each the layers.
The wikipedia page summarizes the layered structure like this:
A layer serves the layer above it and is served by the layer below it. For example, a layer that provides error-free communications across a network provides the path needed by applications above it, while it calls the next lower layer to send and receive packets that comprise the contents of that path. Two instances at the same layer are visualized as connected by a horizontal connection in that layer.
If we take another look at the diagram we can notice that both the TCP and UDP protocols sit right in the middle of the ladder and are separated from the physical layers, where the cable is connected (layer 2). When we unplug the cable the event is immediately detected at the link level (layer 2) but not at the higher levels such as IP (layer 3) and TCP/UDP (layer 4), where no one will be the wiser, and everything will keep working as if nothing had happened.
There is also a secondary aspect to keep in consideration. The TCP protocol always expects ACK (acknowledge) packets from the other end to confirm that a certain fragment of data has arrived. If no ACK is received within a certain amount of time the TCP will re-transmit the data. Combine this with its blindness as to what happens at the lower levels, and we can see why unplugging the cable doesn’t trigger any disconnection event.
To put it in simple terms, TCP is a very patient protocol that can handle moments of “silence” and resend data to make sure the other party will eventually get it. In fact, if we reconnect the cable within a certain amount of time, we’ll be able to resume the communications as if nothing had happened and without data loss.
On the other hand the UDP protocol is a connection-less transport and as a such it doesn’t require to know anything about connection or disconnection events. If we try to send UDP packets while the ethernet or wifi are unplugged the system will simply discard all those packets. Similarly any UDP data coming from a remote host to our device will be lost.
» Mystery solved
So we finally uncovered the puzzle. There are multiple levels of isolation between layers of the networking model and cable/wifi unplug events happen at a different level, than those of UDP and TCP. Also the TCP was inherently designed to withstand temporary blackouts without giving up, which explains why an unplugged cable poses no issues for all existing connections.
In conclusion the lesson to be learned is that pulling the ethernet cable is not a reliable way of testing a sudden disconnection scenario. More often than not nothing will happen.
So how do we simulate a normal, TCP-level disconnection? In the context of SmartFoxServer 2X and for testing the HRC+ events we explain this in our documentation and we provide a method in all supported client API to trigger a sudden disconnection. You can learn all the details in the linked documentation.
» Other causes of disconnections
We have looked into physical disconnections that require unplugging a cable or wifi, but what about other types of disconnections that can affect a client, such as an internet hiccup or an application crash?
Generally speaking network disconnections can happen for a host of reasons. When a device communicates with a remote server it goes through a number of so called “network hops” (or nodes) which are typically represented routers or gateways. Each router can have its own reasons (or issues) to drop a connection and that’s usually what happens when we get kicked out of the internet unexpectedly. (Reasons for dropping a connection can be due to high traffic, unrecoverable errors, etc.)
In those cases SFS2X’s own HRC+ can come to rescue by freezing the server side state of the player and by starting a new session from client side. This way the user will just experience a short moment of interruption before jumping back into the game without loosing his state.
Other situations such as an application crash will not be resumable as the client state is lost, which is an essential part for being able to carry on with the game. In those (hopefully rare) cases we will have to run a new client, login and start a new game.