Reliable Packet Delivery
Reliable TCP sockets generally are considered unsuitable for game networking, for a variety of reasons. Most of the reasons have to do with how the sockets handle congestion and how they prioritize in-order delivery over timeliness. Most games use UDP sockets, which means they send the vast bulk of their gamplay data unreliably. Reliable delivery is still necessary for some subsets of the data, however. To improve reliablity, the XNA Framework provides a reliable delivery mechanism on top of UDP.
The XNA Framework SendData and ReceiveData methods are built over a reliable UDP packet layer. This packet layer provides optional ordering and/or delivery guarantees, plus automatic packet coalescence (if several packets are sent in rapid succession) and splitting (if the payload is to big for a single UDP wire packet) to make efficient use of the underlying UDP channel.
Fundamentally, this is a peer-to-peer architecture with reliable connections from each machine to all other machines. However, this does not place any limitation on what topologies the game can use for its own network traffic. Client-server, peer-to-peer, or any kind of hybrid architecture can benefit from the reliable UDP protocol supported by the XNA Framework.
Packet Delivery Options and Network Performance
- Unreliable, out-of-order (SendDataOptions.None)
- Unreliable, in-order (SendDataOptions.InOrder)
- Reliable, out-of-order (SendDataOptions.Reliable)
- Reliable, in-order (SendDataOptions.ReliableInOrder)
- Chat data (SendDataOptions.Chat)
If a reliable sequential message sent using SendDataOptions.ReliableInOrder is dropped, later sequential messages cannot be delivered until the message is resent and received. In effect, this stalls the channel. If you use this option to send more messages, you are going to see real-world bottlenecks. If the receiver does not call ReceiveData quickly enough or just stops altogether, the queue of messages to resend fills up.
Unreliable sequential messages sent using SendDataOptions.InOrder may have gaps in the sequence, but they will never go backward or stall because of previous non-reliable sequential messages. Unreliably sent data will not be resent. This is good for information that is updated frequently, information such as player position. Newer information will be available by the time the sender attempts to resend the data. For all game data that is sent regardless of the delivery option, always be sure to send the minimum amount of data necessary to communicate the information. This can be done by sending only changes in the game state rather than the entire game state.
For best performance in a network game, minimize the use of reliable and in-order packet delivery. In general, reliable packet delivery should only be used for data critical for your game to function properly, as it consumes bandwidth resending packets as necessary.
SendDataOptions.Chat can be included independently of any other flags, and has two effects. First, any in-order chat sends are only guaranteed to be ordered with regard to other chat sends. There is no guarantee of ordering between non-chat and chat sends. Second, data within a chat send is not encrypted between the sender and receiver.