About the Final Product
After 10 weeks, this post will summarize my goals, and my accomplishments in this projects. This does not necessarily mean that I will be ending this project, but this certainly means that progress on this topic will be on paused for a long while, or until I find a topic within the same realm that requires use of this project. With that said, here’s a summary of my adventures into Reliable-UDP.
The Final Product
The goal of this project was to develop a protocol that was best suited for the fast-paced multiplayer online game that is common today. The protocol I chose to develop is Reliable-UDP, which is a transport layer protocol that aims at sending data in a message-oriented fashion while keeping data reliable. Compared to TCP and UDP protocol, it tries to take the best of both protocols and combine it into one protocol to be used in practice.
R-UDP Protocol aims to have the following behavior:
- Reliable Data Transfer. Reliable for this protocol does not mean to guarantee delivery, but rather guarantees that the sender knows whether or not the message has been delivered. The delivered message is also guaranteed to be sequenced properly and error-free, regardless of its size.
- Connection-Based. Since delivered messages must be aware of whether the message has arrived successfully, a connection-based protocol is needed to achieve that behavior.
- Message-Oriented. Compared to stream-oriented (TCP’s way of message communication), message-oriented only focuses on a per-message basis. Messages do not depend on the state of other messages before the current message being delivered.
With these properties, the R-UDP protocol will allow the application to determine the priority of the messages being delivered. Knowing whether the message has been delivered successfully or not, the application can determine whether the message was of high-priority to re-submit the message, or low-priority to ignore re-submission and continue the process.
In developing the R-UDP protocol, I worked on creating the following:
- Established TCP / UDP Communication
Created wrapper classes for the TCP/UDP Implementation in the Winssock API and abstracted the protocols to allow for easy switching of protocols through a config file.
- Established Reliable-UDP Communication
Developed Reliable-UDP over UDP Socket with TCP behaviors, such as the Three-Way Handshake and the Sliding Window algorithm for sequencing the packets received.
- Performance Testing on TCP / UDP / R-UDP
Researched on Network Emulation for performance testing purposed. This allowed me to test rare cases effectively, such as packet loss, packet error, low bandwidth, etc. The software I used was a combination of Clumsy for packet reordering and quick testing on the same computer, while NEWT (Network Emulation Windows Toolkit) was used for more accurate testing of packet loss, low-bandwidth, etc.
- Server-Client Visual Simulation
Using the TCP, UDP, and R-UDP Communication developed, I created a server-client simulation to showcase some of the notable improvements of the different protocols.
Using the Server-Client Simulation, I managed to trigger the best states of the protocol which well-represents the protocol’s purpose. The following results are performed under network conditions of 30% packet loss, and 10% re-ordering of packets.
TCP Protocol: Stream-Oriented
UDP Protocol: Fast but Unreliable
R-UDP Protocol: Prioritized Data Delivery
On a Final Note
It’s been debated on whether it is worth using protocols such as R-UDP when one can simply use a combination of TCP and UDP. I would argue that using two protocols per client is not wise, as that requires two times the code, two times the socket and ports needed for communication, and will not allow for as much flexibility as protocols that were designed for your use-case.
Although creating your own protocol might not be an efficient use of your time, there are libraries out there that can be used in place of TCP / UDP. One I’ve been meaning to try for myself is ENet, which is essentially taking the ideals of this protocol, but allowing a lot more flexibility than what this currently is. More recently, I’ve caught word of a protocol called QUIC that might pick up as a suitable option over TCP, UDP, and even R-UDP!
I took the time to develop my own protocol solely for learning purposes. Creating R-UDP taught me how to use TCP and UDP, and taught me how TCP worked internally to make it what it is. However, if I were to use a protocol, it would likely come from a more reliable library, and not of my own design.
With that said, I hope you, the readers, have enjoyed my ventures and discussion of the importance of protocols in your future applications.